HTTP/1.1 是用可读文本一问一答的请求—响应(Request-Response)协议。我们把请求报文和响应报文扒开看看里面到底长什么样。
请求报文长什么样?
浏览器请求 /book?id=1 时,发出去的原始 HTTP/1.1 请求报文是这样的:
GET /book?id=1 HTTP/1.1
Host: books.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml
Accept-Encoding: gzip, deflate
Connection: keep-alive
从上往下固定分四块:
- 请求行(Request Line):第一行
GET /book?id=1 HTTP/1.1,用空格隔开请求方法(GET)、请求目标(/book?id=1)和协议版本(HTTP/1.1)。 - 请求标头(Request Headers):紧接着的一行行
字段名: 字段值,比如指明目标站点的Host、声明浏览器型号的User-Agent、声明支持压缩格式的Accept-Encoding。 - 空行(CRLF,
\r\n):极其重要的一行空行,用来告诉服务器“请求头到这儿结束了,下面全是请求体”。 - 请求体(Request Body,可选):客户端提交的数据。
GET请求一般没有请求体;POST和PUT请求会把表单数据、JSON 或上传的文件放在空行后面。
响应报文长什么样?
服务器回传的响应报文结构完全对称:
HTTP/1.1 200 OK
Server: biqu-web
X-App-Version: 3.2.1
Content-Type: text/html; charset=utf-8
Content-Length: 1024
<!doctype html>
<html>
<body>...</body>
</html>
- 状态行(Status Line):第一行
HTTP/1.1 200 OK,包含协议版本、三位状态码(200)和原因短语(OK)。 - 响应标头(Response Headers):比如告诉浏览器正文是什么格式的
Content-Type,告诉浏览器正文有多长的Content-Length。很多正规网站还会在响应头里加上安全策略头:Strict-Transport-Security(HSTS):强制浏览器以后只准用 HTTPS 访问。X-Content-Type-Options: nosniff:不准浏览器瞎猜响应内容类型,老老实实按Content-Type处理。X-Frame-Options: DENY:不准别的网站用<iframe>嵌这个页面,防点击劫持。Content-Security-Policy(CSP):限制页面只能加载白名单里的脚本和资源,防 XSS。
- 空行(CRLF):隔开响应头和响应体。
- 响应体(Response Body):真正的网页 HTML、图片字节或 JSON 数据。
注意
HTTP/1.1 默认开启 Connection: keep-alive(长连接),一条 TCP 连接可以连续收发好几次请求;到了 HTTP/2 改成了二进制帧并支持单连接并发多路复用;HTTP/3 则底层改跑在 UDP 的 QUIC 协议上。而 HTTPS 是在 TCP 握手之后加了一层 TLS 加密,把整条 HTTP 报文(包括路径、查询参数、请求头、Cookie 和请求体)全加密成密文再传,防中间人窃听和篡改。
常见 HTTP 方法
不同的 HTTP 方法代表对资源做不同的动作。做接口测试时要注意区分它是不是只读安全(Safe)的,以及是不是幂等(Idempotent,连发好几次跟发一次结果一样)的:
| 方法 | 用来干什么 | 有请求体吗 | 只读吗 | 幂等吗 |
|---|---|---|---|---|
GET | 读页面或查数据 | 无 | 是 | 是 |
HEAD | 只拿响应头、不要响应体(常用来探测资源在不在) | 无 | 是 | 是 |
OPTIONS | 问服务器支持哪些请求方法或跨域配置 | 无 | 是 | 是 |
POST | 提交数据、触发操作或新增记录(如登录、发帖、加书架) | 有 | 否 | 否(连发两次可能建出两条重复记录) |
PUT | 完整替换指定位置的数据(如把阅读进度存为第 3 章) | 有 | 否 | 是(连存三次“第 3 章”,结果还是第 3 章) |
DELETE | 删除指定资源(如删书评、移出书架) | 通常无 | 否 | 是(删掉之后状态一直是已删除) |
常见 HTTP 状态码
三位数字状态码的百位数代表大类,最常打交道的有这几个:
2xx成功:200 OK:请求成功,响应体里有返回内容。201 Created:新建资源成功(常见于POST)。204 No Content:执行成功,但没有响应体需要返回(常见于DELETE)。
3xx重定向:301 Moved Permanently/302 Found:永久或临时跳转到响应头Location指向的新地址。303 See Other:让浏览器改用GET方法去请求Location新地址,常用于POST提交表单成功后的页面跳转。307 Temporary Redirect:要求跳转时保持原来的请求方法和请求体不变(原来是POST跳转后还发POST)。304 Not Modified:告诉浏览器本地缓存还没过期,不用重下正文。
4xx客户端错误:400 Bad Request:请求参数格式不对或 JSON 写错了。401 Unauthorized:没登录(没带凭证,或者凭证无效)。403 Forbidden:没权限(认识你是谁,但不准你访问这个资源)。404 Not Found:路径或资源不存在。405 Method Not Allowed:路径存在,但不支持你用的 HTTP 方法(比如只收POST的接口你发了GET)。415 Unsupported Media Type:请求体格式不对(比如接口要application/json,你却发了表单格式)。
5xx服务端错误:500 Internal Server Error:后端代码崩了(比如未捕获异常、SQL 报错)。502 Bad Gateway/504 Gateway Timeout:Nginx 等反向代理连不上后面的应用服务,或者等超时了。
要注意区分HTTP 通信成功和业务结果:比如去搜一本不存在的小说,服务器正常查完库,给你返回了一张写着“没有找到匹配的小说”的网页,这时候 HTTP 状态码照样是 200 OK。