跳转至

HTTP 响应

约 1628 个字 39 行代码 预计阅读时间 6 分钟

报文结构

基于浏览器的基础的 HTTP 报文示例:

HTTP/1.1 200 OK
Date: Mon, 20 Jun 2022 03:39:21 GMT
Content-Type: application/json
Content-Length: 735
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Cache: MISS from ts.com
X-Cache-Lookup: MISS from ts.com:3128
Via: 1.1 ts.com (squid/3.5.20)
Connection: keep-alive

{
  "args": {}, 
  "headers": ...(省略)

每行以 CRLF 换行。各部分说明:

Info

并非所有部分必要。需要根据服务端情况给定需要的参数。

  1. 首行分别表示协议、状态码、状态码对应的文本(短语)
  2. Date:报文创建时间
  3. Content-Type:响应的内容类型(MIME)与编码
  4. Content-Length:实体主体长度(字节)
  5. Server:服务端使用的服务器
  6. Access-Control-Allow-Origin:值设置为 * 表示该资源可以被任意外域访问
  7. Access-Control-Allow-Credentials:当浏览器的 credentials 设置为 true 时是否允许浏览器读取 response 的内容
  8. X-Cache:代理服务器 squid 添加,表示浏览器从何处、是在哪个代理缓存载入的网页文件
  9. X-Cache-Lookup:代理服务器 squid 添加,查看代理服务器中是否有某个网页缓存:有就返回 HIT,没有返回 MISS
  10. Via:代理服务器 squid 添加,用来追踪消息转发情况
  11. Connection:服务器发送完响应报文后请保持连接
  12. 接下来的就是实体主体。对于网页来说,一般就是 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 情况。

例:

1
2
3
4
set-cookie: _zap=1e077908-4d18-4aa3-ac32-512ba82660a3; path=/; expires=Wed, 26 Jun 2024 01:13:20 GMT; domain=.zhihu.com
set-cookie: _xsrf=a8d59dff-4b2d-4695-86dc-2d46808e41d6; path=/; domain=.zhihu.com
set-cookie: d_c0="APAf8sLBKBWPTqqxxiV4chyDqjIzzOo_kVQ=|1656292400"; Domain=zhihu.com; expires=Thu, 26 Jun 2025 01:13:20 GMT; Path=/
set-cookie: KLBRSID=d1f07ca9b929274b65d830a00cbd719a|1656292400|1656292400; Path=/

上面表示服务器给用户以下 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

上面表示用户向服务器发送了以下 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 而来,用来防盗链:如果不是从自己的地址来的话,就不让它访问。

GET /img/20191001/qoIB1i5Srrn2.png/imageslim HTTP/1.1
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-US;q=0.7,en-GB;q=0.6
Cache-Control: no-cache
Connection: keep-alive
DNT: 1
Host: static.a4ding.com
Pragma: no-cache
Referer: https://4ading.com/
Sec-Fetch-Dest: image
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: cross-site
Sec-Fetch-Storage-Access: active
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0
sec-ch-ua: "Microsoft Edge";v="137", "Chromium";v="137", "Not/A)Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"