HTTP (Hypertext Transfer Protocol) 协议是一种用于传输超文本的标准协议,它是 Web 通信的基础。HTTP 协议是无状态的,即每次请求是相互独立的,服务器不会记住上一次请求的信息。HTTP 协议采用客户端-服务器模式,客户端发起请求,服务器响应请求,并将响应返回给客户端。
HTTP 协议主要分为以下两个部分:
1.请求:客户端向服务器发送请求,请求包含以下内容:
- 请求方法:GET、POST 等等
- 请求 URL:指明请求的资源的位置
- HTTP 版本:指明请求遵循的 HTTP 协议版本
- 消息头:包含请求的元信息,比如客户端接受的数据类型等
- 消息体:客户端发送的数据,比如表单数据等
2.响应:服务器收到请求后返回响应,响应也包含以下内容:
- HTTP 版本:指明响应遵循的 HTTP 协议版本
- 状态码:用于指定响应的状态,如 200 表示请求成功,404 表示请求的资源不存在等
- 消息头:包含响应的元信息,比如服务器发送的数据类型等
- 消息体:服务器返回的数据,比如 HTML 页面等
HTTP 协议的优点是简单、灵活、可扩展性强,但缺点是通信使用明文,数据容易被窃取或篡改。因此,HTTPS 出现了,它在 HTTP 协议基础上增加了加密与认证功能,使得通信更加安全。
本篇文章主要是对于请求头以及响应头的作用以及在实战中的使用
在浏览器中查看
以edge为例,右键页面,点击检查,选择网络,就可以看到页面的请求信息
请求头(request header)
响应头(response header)
下面列举出一些http请求头头中常用的属性
字段 | 解释 |
---|---|
Accept | 指定客户端能够接收的内容类型 |
Accept-Charset | 浏览器可以接受的字符编码集 |
Accept-Language | 浏览器可接受的语言 |
Cache-Control | 指定请求和响应遵循的缓存机制 |
Connection | 表示是否需要持久连接 |
Cookie | 请求发送时附带的一个或多个Cookie |
Host | 请求的服务器域名或IP地址 |
User-Agent | User-Agent头的内容包含发出请求的用户信息 |
Referer | 表示这个请求是从哪个网页来的,在日志分析、反盗链、统计分析等方面有用 |
Content-Type | 表示请求消息的实体部分的媒体类型 |
Content-Length | 表示请求消息的实体部分的长度 |
Origin | 用于发起一个跨域请求,即请求的服务器与当前页面的服务器不在同一域下 |
If-Modified-Since | 用于请求副本,仅在所请求的资源在指定时间后更新过才返回资源 |
If-None-Match | 当请求头带有If-None-Match时,服务器端会根据请求头中If-None-Match的值与当前页面的ETag是否一致来判断页面是否304 |
Authorization | HTTP授权的授权证书 |
Accept-Encoding | 浏览器可以支持的压缩编码类型 |
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(如果支持) |
Range | 请求头指定第一个字节的位置和最后一个字节的位置来请求文件的一部分 |
TE | 客户端可以接受的传输编码,并通知服务器进行相应的编码 |
If-Range | 如果资源的ETag或Last-Modified时间与指定的相匹配,就返回一段内容,否则就返回整个内容 |
If-Match | 服务器将使用它验证整个资源的一个或多个部分是否未被更改 |
If-Modified-Since | 如果请求的部分在指定时间之后被修改,则请求成功,否则返回304 |
Expect | 请求头允许客户端列出特定的服务器行为,以便在客户端发送请求之前得到服务端的确认 |
下面列举出一些http响应头中常用的属性
字段名 | 解释 |
---|---|
Accept-Ranges | 服务器支持的资源范围 |
Age | 响应持续时间,服务器产生响应的时间与请求时间的差值 |
Cache-Control | 控制缓存的行为 |
Connection | 表示是否需要持久连接(HTTP 1.1默认启用持久连接) |
Content-Encoding | 内容编码方式 |
Content-Language | 内容语言 |
Content-Length | 内容长度 |
Content-Location | 资源在网站中的位置 |
Content-MD5 | 内容的MD5校验值 |
Content-Range | 内容响应的范围 |
Content-Type | 内容类型 |
Date | 响应的时间 |
ETag | 资源的实体标识 |
Expires | 资源过期的时间 |
Last-Modified | 资源的最后修改时间 |
Link | 资源其他相关资源的链接 |
Location | 重定向的地址 |
P3P | 指定P3P策略 |
Pragma | 控制缓存的行为 |
Proxy-Authenticate | 代理服务器要求客户端提供验证信息 |
Refresh | 自动刷新 |
Retry-After | 服务器暂时不可用,指定多久后重试 |
Server | 服务器的信息 |
Set-Cookie | 设置Cookie |
Status | 响应状态码和状态文本 |
Trailer | 允许发送额外的头部 |
Transfer-Encoding | 指明传输编码方式 |
Upgrade | 指明支持协议的版本 |
Vary | 告知缓存机制,响应是否是特定用户代理的请求所匹配 |
Via | 经过的代理服务器 |
Warning | 应用的警告信息 |
WWW-Authenticate | 服务器要求客户端提供验证信息 |
开发中需要注意的字段
Cookie
一些不敏感的客户信息可以写在这个里面
User-Agent
可以用于监听用户设备的ip,例如限定用户账号可以登录几台设备
Content-Type
以下是常见的Content-Type及其对应的媒体类型:
Content-Type | 媒体类型 |
---|---|
text/plain | 纯文本 |
text/html | HTML文档 |
application/json | JSON数据 |
application/xml | XML数据 |
image/jpeg | JPEG图像 |
image/png | PNG图像 |
audio/mpeg | MP3音频 |
video/mp4 | MP4视频 |
以下是一个简单的图表,展示了常见的Content-Type及其所表示的媒体类型:
Content-Type格式 | 媒体类型 | 示例 |
---|---|---|
text/plain | 纯文本 | Hello, World! |
text/html | HTML文档 | <html><body><h1>Hello, World!</h1></body></html> |
application/json | JSON数据 | {"name":"John","age":30,"city":"New York"} |
application/xml | XML数据 | <person><name>John</name><age>30</age><city>New York</city></person> |
image/jpeg | JPEG图像 | (JPEG图片) |
image/png | PNG图像 | (PNG图片) |
audio/mpeg | MP3音频 | (MP3音频) |
video/mp4 | MP4视频 | (MP4视频) |
Authorization
这里可以存储认证信息,用于控制用户或应用程序对资源的访问。在Web应用程序中,通常使用标准的HTTP授权头来传递授权信息。常见的授权机制包括基本认证、摘要认证、OAuth和JSON Web Token等。
springboot修改响应头
方案一
例如,下面的代码演示了如何将响应头中的Content-Type设置为application/json:
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping("/myapi")
public ResponseEntity<String> getMyApi() {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
return new ResponseEntity<>("{\"message\":\"hello world\"}", headers, HttpStatus.OK);
}
}
在这个例子中,我们创建了一个HttpHeaders对象并将Content-Type设置为application/json,然后将其与响应正文和状态码一起传递给ResponseEntity构造函数。
当客户端调用/myapi时,响应头将包含Content-Type: application/json,而不是默认的Content-Type: text/plain。
方案二
在使用HttpServletRequest和HttpServletResponse对象处理HTTP请求和响应时,可以使用HttpServletResponse对象来对响应进行修改。下面是一个简单的例子,演示如何使用HttpServletResponse对象来设置响应头和响应内容:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应头
response.setContentType("text/plain;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
// 获取输出流
PrintWriter out = response.getWriter();
// 输出响应内容
out.println("Hello World!");
// 关闭输出流
out.close();
}
在这个例子中,我们首先使用response.setContentType()方法设置响应的内容类型为"text/plain;charset=UTF-8",这样浏览器就知道如何正确解析响应内容。然后,我们使用response.setHeader()方法设置响应头的"Cache-Control"属性值为"no-cache",这样浏览器就不会缓存页面。最后,我们使用response.getWriter()方法获取输出流,然后使用PrintWriter对象的println()方法输出"Hello World!"作为响应内容,最后关闭输出流。
需要注意的是,在调用任何输出方法之前,必须先设置响应头和状态码,否则将会抛出IllegalStateException异常。例如,如果您不设置响应类型并尝试输出响应内容,就会抛出以下异常:
java.lang.IllegalStateException: Cannot call getWriter(), getOutputStream() already called
因此,请务必确保在使用HttpServletResponse对象之前正确设置响应头和状态码。