HTTP 协议分析
超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议[1]。HTTP是万维网的数据通信的基础。 —— Wikipedia
尽管TCP/IP协议是互联网上最流行的应用,但是在HTTP协议中并没有规定它必须使用或它支持的层。事实上HTTP可以在任何互联网协议或其他网络上实现。HTTP假定其下层协议提供可靠的传输。因此,任何能够提供这种保证的协议都可以被其使用,所以其在TCP/IP协议族使用TCP作为其传输层。
请求方法
- GET —— 向指定的资源发出“显示”请求。
- HEAD —— 与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。
- POST —— 向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
- CONNECT —— HTTP/1.1协议中预留给能够将连接改为隧道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。
HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。当然,所有的方法支持的实现都应当符合下述的方法各自的语义定义。
HTTP 版本迭代
HTTP/0.9
已过时。只接受GET一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持POST方法,因此客户端无法向服务器传递太多信息。
HTTP/1.0
这是第一个在通讯中指定版本号的HTTP协议版本。
HTTP/1.1
默认采用持续连接(Connection: keep-alive),能很好地配合代理服务器工作。还支持以管道方式在同时发送多个请求,以便降低线路负载,提高传输速度。
HTTP/1.1相较于HTTP/1.0协议的区别主要体现在:
- 缓存处理
- 带宽优化及网络连接的使用
- 错误通知的管理
- 消息在网络中的发送
- 互联网地址的维护
- 安全性及完整性
HTTP/2
当前版本,于2015年5月作为互联网标准正式发布。
HTTP 状态码
响应类型
状态类型 | 信息 |
---|---|
1xx | 指示信息–表示请求已接收,继续处理。 |
2xx | 成功–表示请求已被成功接收、理解、接受。 |
3xx | 重定向–要完成请求必须进行更进一步的操作。 |
4xx | 客户端错误–请求有语法错误或请求无法实现。 |
5xx | 服务器端错误–服务器未能实现合法的请求。 |
常见状态码 | |
---|---|
200 OK | 客户端请求成功 |
400 Bad Request | 客户端请求有语法错误,不能被服务器所理解 |
401 Unauthorized | 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 |
403 Forbidden | 服务器收到请求,但是拒绝提供服务 |
404 Not Found | 请求资源不存在,举个例子:输入了错误的URL |
500 Internal Server Error | 服务器发生不可预期的错误 |
503 Server Unavailable | 服务器当前不能处理客户端的请求,一段时间后可能恢复正常 |
持续连线
在HTTP 0.9和1.0中,TCP连接在每一次请求/回应对之后关闭。在HTTP 1.1中,引入了保持连线的机制,一个连接可以重复在多个请求/回应使用。持续连线的方式可以大大减少等待时间,因为在发出第一个请求后,双方不需要重新执行TCP握手程序。
抓包分析
建立TCP链接
三次握手🤝
请求头
GET
- 请求方式 GET
- Host: log.people.cn
- User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62
- Accept: */* 接受所有类型
- Accept-Encoding: gzip, deflate 接受的编码类型
- Accept-Language: zh-CN,zh;q=0.9, en;q=0.8, en-GB;q=0.7, en-US;q=0.6 对不同语言的偏好
- If-Modified-Since:Fri, 24 Dec 2021 03:27:02 GMT 服务器文件上次修改时间
- Referer: http://www.people.com.cn
POST
- 请求类型:POST
- Host: search.people.cn
- Content-Length: 145 内容长度 145字节
- Accept: application/json, text/plain,*/*
- Content-Type: application/json 内容类型为应用数据,格式为json
- 包内包含了一个大小为145bytes的json文件,发送要搜索的数据信息
响应头
-
状态码: 200
-
Response Phrase: OK
请求成功
-
Connection: Keep-alive
-
Content-Encoding: gzip 内容编码 gzip
-
Content-Type: text/html 内容格式 text/html
-
Date:Mon, 28 Mar 2022 16:29:49 GMT
-
Server:nginx 服务器运行的系统
-
Vary:Accept-Encoding 代表在下次的请求头中还需包含Accept-Encoding条目
- 状态码:403 Forbidden
- Transfer-Encoding: chunked
- Transfer-Encoding 指明了将实体报文安全传递给用户所采用的编码形式。
- chunked指数据以一系列分块的形式进行发送。
Content-Length
首部在这种情况下不被发送。
Node.js 实现
刚好最近在学Node.js, 尝试使用node.js 配置服务器后端响应。
对GET请求的响应
创建一个最简单的对GET请求的响应,当收到GET请求时返回一个text文件
使用 API Tester 向 127.0.0.1:3000
端口发送一个GET请求
可以发到返回的内容为一个text,长度为11字节
获取服务器中的文件
判断逻辑为,向服务器发送GET请求,如果该用户存在,会返回用户名对应的json文件,如果data中没有该用户的信息,则返回404错误,提示‘no user’
-
不存在的用户名,返回404错误码
-
存在的用户,返回对应的json文件
对POST请求的响应
-
如果请求为POST,并且访问的路径为
api/v1/user
进入函数解析 -
如果数据校验出错,返回状态码 422 ,提示``name required`
-
如果请求正确,且数据符合要求,返回状态码200,并且返回一个json文件,内容为
{ "success": true }
-
其他情况,调用错误处理函数兜底,返回错误码400
测试
发送一个body为空的POST请求,服务器响应422 name required
,说明缺少内容
访问其他路径,返回400 Error
发送一个POST报文,body包含一个json字段
在请求报文的头部加入Content-Type为 json类型
服务器返回的信息为
{"success":true}
在本地的data文件夹中成功创建了名为pqq.json
的文件