WebKitFormBoundary导致Jmeter Post表单后端收不到数据,原因分析
现象
使用Jmeter模拟浏览器构造Post请求时,在header中有如下字段
content-type: multipart/form-data; boundary=----WebKitFormBoundary6UAvXfMl62j1mySR
如果照着浏览器的header复制粘贴进jmeter的http请求头管理器中,会导致后端接受不到请求数据。
解决
解决很简单,去掉这行content-type这一行即可
原因
原因要追溯到 RFC1867协议 HTTP file upload这一部分。
- 在1995年,ietf 发布了 rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上传。Content-Type 的类型扩充了multipart/form-data 用以支持向服务器发送二进制或者非ASCALL(no-ascll)数据。
- multipart/form-data重要规范特征:
- 必须post方式发送数据;
- Content-Type格式为multipart/form-data; boundary=${boundary}。满足条件的提交,浏览器会自动创建boundary。对于webkit内核的浏览器例如chrome和edge,自动创建的boundary格式如下,(其中boundary是长度为16的随机base64字符)
----WebKitFormBoundary${boundary}
- 发送数据内容以----WebKitFormBoundary${boundary}作为起始标记和分隔符、终结标记多了“--”;数据内容主要包括:Content-Disposition、Content-Type、数据内容等;其中数据内容前面有\n\r标记的空行;Content-Disposition是必选项,其它都是可选项;Content-Disposition 包含了 type 和 一个名字为 name 的 parameter,type 是 form-data,name 参数的值则为表单控件(username)的名字,如果是文件,那么还有一个 filename 参数,值就是文件名。
例如:
------WebKitFormBoundary6UAvXfMl62j1mySR
Content-Disposition: form-data; name="saveType"
send
------WebKitFormBoundary6UAvXfMl62j1mySR
Content-Disposition: form-data; name="createOperator"
平台
------WebKitFormBoundary6UAvXfMl62j1mySR
Content-Disposition: form-data; name="createOperatorType"
02
------WebKitFormBoundary6UAvXfMl62j1mySR
Content-Disposition: form-data; name="cpnName"
结论
所以,对于类似Jmeter、Postman这一类接口工具来说,只需在http请求中勾选“对Post使用multipart/form-data”选项,请求在构造时会自动在header与body中带上WebKitFormBoundary,无需用户自己在header中定义。
强行自己定义则会导致header中的WebKitFormBoundary与body中自动生成的WebKitFormBoundary值不一致,导致后端无法使用Boundary分割form表单内容。