一剑化三清:
全真教上乘剑术,通过手腕抖动,能使每一剑均可化为三招。
为 杨过 和 小龙女 一同参研领悟所学,
因剑法传到古墓,故为 王重阳 所创,并且为 林朝英 所得
Content-Type 是指 http/https 发送信息至服务器时的内容编码类型,用于 表明发送数据流的类型,服务器根据编码类型使用特定的解析方式,获取数据流中的数据。
下面详细介绍一下常用的类型及如何使用 Python 模拟:
application/x-www-form-urlencoded
最常见的 POST 提交数据的方式了。浏览器原生 <form>
表单,如果不设置 enctype
属性,那么最终就会以 application/x-www-form-urlencoded
方式提交数据。
首先,Content-Type
被指定为 application/x-www-form-urlencoded
,其次,提交的数据按照 key1=val1&key2=val2
的方式进行编码,key
和 val
都进行了 url 编码。
form 表单
<form action="/" method="POST">
...
</form>
Fiddler 抓包分析
Python requests 模拟请求
import requests
data = {
'username': 'admin',
'password': 'admin'
}
response = requests.post('http://httpbin.org/post', data=data)
Requests 库支持以 form表单形式发送 post请求,只需要将请求的参数构造成一个字典,然后传递给 `requests.post()` 的 `data` 参数即可
multipart/form-data
又是一个常见的 POST 数据提交的方式。我们使用表单上传文件的时候,必须将 <form>
表单的 enctype
设置为 multipart/form-data
-
multipart/form-data
的基础是 post 请求,即基于 post 请求来实现的 -
multipart/form-data
形式的 post 与普通 post 请求不同之处体现在 请求头,请求体 两部分
请求头
必须包含 Content-Type
信息,且其值也必须规定为 multipart/form-data
,同时还需要规定一个内容分割符用于分割请求体中不同参数的内容。具体的信息格式如下:
Content-Type: multipart/form-data; boundary=${bound}
其中 ${bound}
是一个占位符,代表我们规定的具体分隔符,可以自己任意规定,但为了避免和正常文本重复,尽量使用复杂一点的内容。如:
Content-Type: multipart/form-data; boundary=e0722295b17a922fdd0c86a3f2cdd47d
-
请求体
--${bound} Content-Disposition: form-data; name="username" admin --${bound} Content-Disposition: form-data; name="password" admin --${bound} Content-Disposition: form-data; name="file"; filename="cookie_me.py" ... --${bound}--
其中 ${bound}
就是之前请求头信息中的分隔符,两者需要保持一致。
另外,请求体被 分隔符 划分为 3 个部分,每个部分就是一个参数的键值描述(类似普通post请求中 k1=v1
部分),但对参数信息的描述可以比普通post请求更加丰富,这就是为什么 multipart/form-data
能发送文件的原因。
每一个部分都是以 --${bound}
开始的,接着是该部分内容的描述信息,然后是一个回车,最后是描述信息的具体内容,最后的分隔符会以 --
结尾,表示请求体结束
form 表单
<form action="/" method="POST" enctype="multipart/form-data">
...
</form>
Fiddler & Chrome Network 抓包分析
Python requests 模拟请求
# 仅传递文件
files = {
'file': open('./test.py', 'r')}
response = requests.post('http://127.0.0.1', files=files)
# 仅传递参数
data = {
'username': (None, 'admin'),
'password': (None, 'admin')
}
response = requests.post('http://127.0.0.1', files=data) # 此处为 files
# 文件 + 参数
data = {
'username': 'admin',
'password': 'admin'
}
files = {
'file': open('./test.py', 'r')}
response = requests.post('http://127.0.0.1', files=files, data=data)
注意:不需要设置
Content-Type: multipart/form-data
请求头此外,还可以采用 requests-toolbelt 库构建参数
application/json
由于 JSON 规范的流行,越来越多程序把 application/json
作为请求头,用来告诉服务端消息主题是序列化后的 JSON 字符串。除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify
,服务端语言也都有处理 JSON 的函数
JSON 格式支持比键值对复杂得多的结构化数据,可以视为 application/x-www-form-urlencoded
的升级版,特别适合 RESTful
接口
Fiddler & Chrome Network 抓包分析
Python requests 模拟请求
# 第一种方式
data = {
'username': 'zzzzls',
'password': 'zzzzls'
}
response = requests.post('http://127.0.0.1', json=data)
# 第二种方式
headers = {
'Content-Type': 'application/json'}
data = {
'username': 'zzzzls',
'password': 'zzzzls'
}
response = requests.post('http://127.0.0.1', data=json.dumps(data), headers=headers)