熟悉POST提交数据的4种方式,接口测试更高效
Hi,大家好。我们都知道POST一般用于向服务端提交数据,POST提交数据的 4
种格式即Content-Type的4种形式,尤其注意每种格式中http发送请求时body中数据的格式。4种形式分别是:
-
application/x-www-form-urlencoded:URL encoded。
-
multipart/form-data:键值对型数据。
-
application/json:Json 类型数据。
-
text/xml:xml。
前言
HTTP/1.1 协议规定的 HTTP 请求方法有OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 几种。POST通常用来向服务端提交数据,主要用于提交表单、上传文件。
HTTP 协议是以ASCII码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为四个部分:请求行、请求头、空行、请求体。类似于这样:
协议规定 POST 提交的数据必放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。
但是数据发送出去,还要服务端解析成功才有意义。一般服务端语言如PHP、Python 等,以及它们的framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以说到POST提交数据方案,包含了Content-Type 和消息主体编码方式两部分,以下就正式开始介绍它们。
application/x-www-form-urlencoded
1、介绍
这是最常见的 POST 提交数据的方式,浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉):
首先,Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key和val都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。
很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 的 Ajax,Content-Type 默认值都是application/x-www-form-urlencoded;charset=utf-8。
2、实例
编写Python代码:
requests 根据传入的键来判断采用哪种方法,以上采用 urlencode 的方法编码数据。这里面是给data=传入参数,参数格式是 Python dict字典。
打印输出如下:
{
"args": {},
"data": "",
"files": {},
"form": {
"age": "18",
"name": "coco"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "16",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-61ab2730-50a148997859a1ec6be91aa0"
},
"json": null,
"origin": "121.35.100.58",
"url": "http://httpbin.org/post"
}
multipart/form-data
1、介绍
这种编码方式通常是用在客户端向服务端传送大文件数据,如:图片或者文件,是常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让<form>表单的 enctype 等于 multipart/form-data,上传文件用的就是这种格式,直接来看一个请求示例:
POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
首先会生成一个 boundary 字符串分界线,表明下面的都是表单内容,然后紧接着跟的是表单中的第一个键值对中的名称,而后一个换行,跟着值。再生成一个boundary 字符串分界线,用于分割不同的键值。如果传输的是文件,还要包含文件名和文件类型信息。这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。
上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 <form> 表单也只支持这两种方式(通过 <form> 元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded。其实 enctype 还支持 text/plain,不过用得非常少)。
随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式。
2、实例
编写Python代码:
import requests
from requests_toolbelt import MultipartEncoder
m = MultipartEncoder(
fields={'field0': 'value1', 'field1': 'value2', 'field2': ('filename', open('data.txt', 'rb'), 'text/plain')}
)
content = requests.post('http://httpbin.org/post', data=m,headers={'Content-Type': m.content_type}).text
print(content)
print(m.content_type)
同样也是data=传参,不同的是数据的编码方式不同。
打印输出如下:
{
"args": {},
"data": "",
"files": {
"field2": ""
},
"form": {
"field0": "value1",
"field1": "value2"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "358",
"Content-Type": "multipart/form-data; boundary=dd748892469a4b1d9b66f4ef3c875314",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-61ab2927-40509795067605f976c44f9a"
},
"json": null,
"origin": "121.35.100.58",
"url": "http://httpbin.org/post"
}
multipart/form-data; boundary=dd748892469a4b1d9b66f4ef3c875314
application/json
1、介绍
application/json 作为响应头大伙肯定不陌生,用得超级多,也非常方便。设置 header 中Content-type,就告诉服务端数据以Json字符串的形式存在,相应的就用Json的方法解码数据即可。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的Json字符串。由于Json 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理Json的函数,使用Json不会遇上什么麻烦。
Json格式支持比键值对复杂得多的结构化数据,Google 的 AngularJS 中的 Ajax 功能,默认就是提交Json字符串。例如下面这段代码:
最终发送的请求是:
这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。各大抓包工具如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示Json 数据,非常友好。
2、实例
编写Python代码:
利用json=传入参数,参数的格式 Json 字符串,所以需要使用 json.dumps(), 将 Python dict 转 Json 字符串(其实就是 Python 的 str 类型,但是接收方会对字符串进行Json解码)。
打印输出如下:
{
"args": {},
"data": "\"{\\\"name\\\": \\\"coco\\\", \\\"hobby\\\": \\\"coding\\\"}\"",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "45",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-61ab2a62-57152a3a2edb5caa5f5a9351"
},
"json": "{\"name\": \"coco\", \"hobby\": \"coding\"}",
"origin": "121.35.100.58",
"url": "http://httpbin.org/post"
}
text/xml
1、介绍
它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。典型的 XML-RPC 请求是这样的:
XML-RPC 协议简单、功能够用,各种语言的实现都有。它的使用也很广泛,如 WordPress 的 XML-RPC Api,搜索引擎的 ping 服务等等。JavaScript 中,也有现成的库支持以这种方式进行数据交互,能很好的支持已有的 XML-RPC 服务。不过,个人觉得 XML 结构还是过于臃肿,一般场景用Json会更灵活方便。
2、实例
编写Python代码:
import requests
# from requests_toolbelt import MultipartEncoder
p_data = """
<?xml version="1.0"?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4>41</i4></value>
</param>
</params>
</methodCall>
"""
content = requests.post(url='http://httpbin.org/post',data=p_data,headers={'Content-Type':'text/xml'}).text
print(content)
利用data=传参,参数类型是字符串,须按照 xml 的语法写。
打印输出如下:
{
"args": {},
"data": "\n<?xml version=\"1.0\"?>\n<methodCall>\n <methodName>examples.getStateName</methodName>\n <params>\n <param>\n <value><i4>41</i4></value>\n </param>\n </params>\n</methodCall>\n",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "200",
"Content-Type": "text/xml",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.24.0",
"X-Amzn-Trace-Id": "Root=1-61ab2b3c-3e4f5e570e15c53f19ab13a7"
},
"json": null,
"origin": "121.35.100.58",
"url": "http://httpbin.org/post"
}
感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接免费拿走:
① 2000多本软件测试电子书(主流和经典的书籍应该都有了)
② 软件测试/自动化测试标准库资料(最全中文版)
③ 项目源码(四五十个有趣且经典的练手项目及源码)
④ Python编程语言、API接口自动化测试、web自动化测试、App自动化测试(适合小白学习)
⑤ Python学习路线图(告别不入流的学习)
上图的资料 在我的QQ技术交流群里(技术交流和资源共享,广告进来腿给你打断)
可以自助拿走,群号953306497(备注“csdn111”)群里的免费资料都是笔者十多年测试生涯的精华。还有同行大神一起交流技术哦。
相关文章
- 完全不写测试脚本,不研究代码,月薪30K的路径
- 利用IAR Timeline工具测试delay函数执行时间
- 接口测试这件小事
- jmeter并发接口测试教程_jmeter高并发测试
- JMeter 测试笔记(一):认识JMeter
- 测试平台解决了什么问题?
- 测试之路 pytest接口自动化-request包中的headers覆盖
- 看了那么多接口测试文章,只有这篇写明白了
- 完整版在xcode打测试专用ipa包流程
- 测试之路 pytest接口自动化框架-yaml数据驱动
- 测试之路 pytest接口自动化框架扩展-params数据解析
- 测试之路 pytest接口自动化框架扩展-json数据解析
- 全网最详细的postman接口测试教程,一篇文章满足你
- API接口测试-postman自动生成测试报告
- 接口测试第4讲:Restful API
- 软件测试|如何实现多套环境的接口自动化测试
- 接口测试|HttpRunner获取响应数据&extract提取值到变量
- 使用Postman工具做接口测试(一)——基本功能介绍
- 基于Python接口自动化测试框架+数据与代码分离实战(优化篇)
- 接口测试的测试要点
- 接口自动化测试多场景实践 - 上篇
- 腾讯出品小程序自动化测试框架【Minium】系列(五)API详解(中)
- 慢速http测试(dos攻击)
- Selenium Web自动化测试学习(一)
- Postman 批量测试接口详细教程
- 腾讯轻联测试预览报错怎么办?
- Python 接口测试之获取接口数据封装
- 快速入门Kali Linux渗透测试(kalilinux渗透教程)
- 接口测试笔记二详解编程语言
- 中国空间站天和核心舱完成在轨测试验证
- 早期基准测试结果表明Win11的性能比Win10最多高15%
- 设置VMware随系统开机自动启动并引导虚拟机操作系统(测试成功!So Easy~~~~)
- 如何快速搭建一个适用于测试的Linux环境?(搭建linux测试环境)