HTTP 响应
约 1628 个字 39 行代码 预计阅读时间 6 分钟
报文结构
基于浏览器的基础的 HTTP 报文示例:
每行以 CRLF 换行。各部分说明:
Info
并非所有部分必要。需要根据服务端情况给定需要的参数。
- 首行分别表示协议、状态码、状态码对应的文本(短语)
Date
:报文创建时间Content-Type
:响应的内容类型(MIME)与编码Content-Length
:实体主体长度(字节)Server
:服务端使用的服务器Access-Control-Allow-Origin
:值设置为*
表示该资源可以被任意外域访问Access-Control-Allow-Credentials
:当浏览器的credentials
设置为true
时是否允许浏览器读取response
的内容X-Cache
:代理服务器 squid 添加,表示浏览器从何处、是在哪个代理缓存载入的网页文件X-Cache-Lookup
:代理服务器 squid 添加,查看代理服务器中是否有某个网页缓存:有就返回 HIT,没有返回 MISSVia
:代理服务器 squid 添加,用来追踪消息转发情况Connection
:服务器发送完响应报文后请保持连接- 接下来的就是实体主体。对于网页来说,一般就是 HTML 代码。
HTTP 状态码
标准的 HTTP 状态码一共有五大类,通常为三位数字:
- 1XX:信息响应
- 2XX:成功响应
- 3XX:重定向消息
- 4XX:客户端错误响应
- 5XX:服务器错误响应
一些状态码用于 WebDAV、HTTP Delta Encoding,一些目前不使用,一些非标准(如微软、nginx 扩展了一堆 HTTP 状态码,用于自己的服务器)。
返回什么状态码,由服务器上的代码决定,不一定是描述上的问题,后面都是建议标准。
常用的状态码
状态码 | 短语 | 描述 |
---|---|---|
200 | OK | 请求成功。成功的含义取决于 HTTP 方法: - GET:资源已被提取并在消息正文中传输。 - HEAD:实体标头位于消息正文中。 - PUT / POST:描述动作结果的资源在消息体中传输。 - TRACE:消息正文包含服务器收到的请求消息。 |
301 | Moved Permanently | 请求资源的 URL 已永久更改。 在响应中给出了新的 URL。 |
302 | Found | 此响应代码表示所请求资源的 URI 已暂时更改。 未来可能会对 URI 进行进一步的改变。 因此,客户机应该在将来的请求中使用这个相同的 URI。 |
304 | Not Modified | 这是用于缓存的目的。 它告诉客户端响应还没有被修改,因此客户端可以继续使用相同的缓存版本的响应。 |
401 | Unauthorized | 客户端必须对自身进行身份验证才能获得请求的响应。 |
403 | Forbidden | 客户端没有访问内容的权限; 也就是说,它是未经授权的,因此服务器拒绝提供请求的资源。 与 401 不同,服务器知道客户端的身份。 |
404 | Not Found | 服务器找不到请求的资源。 在浏览器中,这意味着无法识别 URL。 在 API 中,这也可能意味着端点有效,但资源本身不存在。 服务器也可以发送此响应,而不是 403,以向未经授权的客户端隐藏资源的存在。 这个响应代码可能是最广为人知的,因为它经常出现在网络上。 |
407 | Proxy Authentication Required | 类似于 401,但是认证需要由代理完成。 如果内网访问外网需要代理,而代理服务器需要账号密码,如果未提供正确的账号密码,会返回该错误 |
500 | Internal Server Error | 服务器遇到了不知道如何处理的情况。 |
502 | Bad Gateway | 服务器作为网关需要得到一个处理这个请求的响应,但是得到一个错误的响应。 |
503 | Service Unavailable | 服务器没有准备好处理请求。 常见原因是服务器因维护或重载而停机。 请注意,与此响应一起,应发送解释问题的用户友好页面。 这个响应应该用于临时条件;如果可能的话,HTTP Retry-After 首字段应该包含恢复服务之前的估计时间。 网站管理员还必须注意与此响应一起发送的与缓存相关的标头,因为这些临时条件响应通常不应被缓存。 |
504 | Gateway Timeout | 服务器充当网关,且无法及时获得响应。 |
Cookie(s)
Cookie(s) 是一种服务器用来标识用户的手段,通常用于自动登录、追踪用户、精准推送广告。
接收
用户向服务器发送请求时,服务器可以在响应首部里面添加 set-cookie 字段来向用户的浏览器添加 Cookie。
Cookie 一般仅对某一类主机有效,且有有效期。
Cookie 是明文存储的。
可以通过开发人员工具的“网络”“应用程序”查看 Cookie 情况。
例:
上面表示服务器给用户以下 Cookie:
名 | 值 | 域 | 路径 | 过期时间(如无则仅对当前会话有效) |
---|---|---|---|---|
_zap |
1e077908-4d18-4aa3-ac32-512ba82660a3 |
.zhihu.com |
/ |
2024-06-26 01:13:20 GMT |
_xsrf |
a8d59dff-4b2d-4695-86dc-2d46808e41d6 |
.zhihu.com |
/ |
|
d_c0 |
APAf8sLBKBWPTqqxxiV4chyDqjIzzOo_kVQ=\|1656292400 |
zhihu.com |
/ |
2025-06-26 01:13:20 GMT |
KLBRSID |
d1f07ca9b929274b65d830a00cbd719a\|1656292400\|1656292400 |
/ |
发送
此后用户向服务器发送请求时,会自动在请求首部的 cookie 字段中附上对该地址有效的 Cookie:
上面表示用户向服务器发送了以下 Cookie:
名 | 值 |
---|---|
SESSIONID |
ydsZFF2QiHcMaA32p4DUwk3IsctckJMnF6EQkQ9e4f2 |
JOID |
V1wcCkpq9aa5ms2vQWZAu71Yj4tYSNuFkr3vgWJN14iaseqNb1L8F9efwaJJCdfJjrVPR97YS12edABtlhsR33Q= |
osd |
W1gdAUlm8aeymcGrQG1Dt7lZhIhUTNqOkbHrgGlO24ybuumBa1P3FNubwKlKBdPIhbZDQ9_TSFGadQtumh8Q1Hc= |
_zap |
1e077908-4d18-4aa3-ac32-512ba82660a3 |
_xsrf |
a8d59dff-4b2d-4695-86dc-2d46808e41d6 |
d_c0 |
APAf8sLBKBWPTqqxxiV4chyDqjIzzOo_kVQ=\|1656292400 |
Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49 |
1656054195,1656290715,1656292123,1656292403 |
Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49 |
1656292403 |
KLBRSID |
d1f07ca9b929274b65d830a00cbd719a\|1656292403\|1656292400 |
captcha_session_v2 |
2\|1:0\|10:1656292404\|18:captcha_session_v2\|88:eENjQ2V2cTBZU0VpcHh2eVVLbFlBZXZTc1VBWS9oSmRzUFVYQk91S3lwSVowMDZVcmhLSHZUZmhIMzZkYjkrVg==\|d0912c33fd53a0c392d3fe5283486c2f8bbf2eab76752f604a319206b5513c4c |
Session、本地存储(Local Storage)
Cookie 实际上可随意编辑,在安全性不高的场合,用户可以伪造他人的 Cookie。
Session 的实质仍然是 Cookie,但是服务器会给用户一个 ID,在服务器段验证用户身份。
本地存储也可以用来验证用户身份,但不是通过 HTTP 请求,而是通过 JS 代码读写的。
Referer
注意拼写
这个名称实际上是 referrer 的误写,但是现在也改不过来了。
浏览器在同一个会话,从第二次发送 HTTP 请求开始,会加上这个首部字段。这个字段一般会记录来源 URL,意思就是用户从哪里来。
URL 中的 #xxxx
和 用户名:密码@
这两个部分不会在里面。
一些服务器用该字段检测图片等资源是否从特定 URL 而来,用来防盗链:如果不是从自己的地址来的话,就不让它访问。