前言
日常使用,经常使用HTTP协议,今天简单总结下。
HTTP报文样例
以下是一个HTTP报文样例
GET /api/random HTTP/1.1
Host: 127.0.0.1:5000
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: none
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: jenkins-timestamper-offset=-28800000; jenkins-timestamper=system; jenkins-timestamper-local=true
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 25
Access-Control-Allow-Origin: *
Server: Werkzeug/0.15.5 Python/3.7.3
Date: Wed, 04 Sep 2019 14:18:08 GMT
{
"randomNumber": 40
}
HTTP 请求报文结构
- 请求行 -- 包含用于请求的方法、请求 URI 和 HTTP 版本。
如上面例子
GET /api/random HTTP/1.1
- 请求头 -- 这里通常就是我们说的
Headers
,包含表示请求的各种条件和属性的各类首部。(通用首部、请求首部、实体首部以及RFC里未定义的首部如 Cookie 等)
格式为:
头部字段名 + 冒号(:) + 值 + 回车符 + 换行符
如上面例子
Host: 127.0.0.1:5000
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: none
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: jenkins-timestamper-offset=-28800000; jenkins-timestamper=system; jenkins-timestamper-local=true
- 空一行 -- 表示请求头部结束,这一行必不可少。
- 请求正文 -- 这里通常就是我们说的
Body
。一般
使用在 POST 方法中, GET 方法一般
不存在请求正文。
如上面例子,body没有数据
HTTP 响应报文结构
- 状态行 -- 包含表明响应结果的HTTP 版本、状态码和状态码描述 。
如上面例子,其中200 是状态码
HTTP/1.0 200 OK
- 响应头 -- 这里通常就是我们说的
Headers
,包含表示请求的各种条件和属性的各类首部。(通用首部、响应首部、实体首部以及RFC里未定义的首部如 Cookie 等)
格式为:
头部字段名 + 冒号(:) + 值 + 回车符 + 换行符
如上面例子
Content-Type: application/json
Content-Length: 25
Access-Control-Allow-Origin: *
Server: Werkzeug/0.15.5 Python/3.7.3
Date: Wed, 04 Sep 2019 14:18:08 GMT
- 空一行 -- 表示响应头部结束,这一行必不可少。
- 响应正文 -- 这里通常就是我们说的
Body
。
如上面例子,body有数据
{
"randomNumber": 40
}
HTTP 常用响应状态码
- 200 = 响应成功
- 301 = 请求的网页
已永久
移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。 - 302 = (
临时移动
) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 - 400 = (错误请求) 服务器不理解请求的语法。
- 403 = (禁止) 服务器拒绝请求。
- 404 = (未找到) 服务器找不到请求的网页。
- 500 = (服务器内部错误) 服务器遇到错误,无法完成请求。
Python请求HTTP接口样例
这里以GET
和POST
请求方法method为例
- GET 请求-无参数
import requests
r = requests.get('http://127.0.0.1:5000/api/random')
- GET 请求-有参数
import requests
params = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://127.0.0.1:5000/api/random', params=params)
- POST请求-没有请求参数params,没有请求body
import requests
r = requests.post('http://127.0.0.1:5000/api/random')
- POST请求-有请求参数params
import requests
params = {'key1': 'value1', 'key2': 'value2'}
r = requests.post('http://127.0.0.1:5000/api/random', params=params)
- POST请求-有请求参数params,有请求body,但非json格式。
如请求body为key3=value3&key4=value4
import requests
params = {'key1': 'value1', 'key2': 'value2'}
body = {'key3': 'value3', 'key4': 'value4'}
r = requests.post('http://127.0.0.1:5000/api/random', params=params, data=body)
- POST请求-有请求参数params,有请求body为json格式
如请求body为{"key3": "value3", "key4": "value4"}
import requests
params = {'key1': 'value1', 'key2': 'value2'}
body = {'key3': 'value3', 'key4': 'value4'}
r = requests.post('http://127.0.0.1:5000/api/random', params=params, data=json.dumps(body))
或者
import requests
params = {'key1': 'value1', 'key2': 'value2'}
body = {'key3': 'value3', 'key4': 'value4'}
r = requests.post('http://127.0.0.1:5000/api/random', params=params, json=body)
分块传输CHUNKED编码
分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供,表示Body
里的数据将用chunked编码传输内容。
Transfer-Encoding: chunked
根据定义,浏览器不需要等到内容字节全部下载完成,只要接收到一个chunked块就可解析页面。并且可以下载html中定义的页面内容,包括js,css,image等。
- 每个分块的格式都是一致的:
length<CR><LF>
data<CR><LF>
length是十六进制的数据长度.
- 最后一个分块比较特殊,他是一个0长度的分块,表示数据结束.这时候接收端就认为这次的数据已经读取完成了.
如下面例子:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25
This is the data in the first chunk
1A
and this is the second one
0