刚开始做小程序对接的时候,很多人一上来就问为啥这个接口请求不成功,完全都不知道自己看看HTTP的请求信息,因为 wx.request
没有设置content-type
,默认的 content-type
是 application/json
。但是我们平常后端接受的一般都是 application/x-www-form-urlencoded
。用惯了jQuery的$.ajax今天来说说请求的细节。
Request Payload& FormData
- Request Payload
对应content-type:application/json,axios默认使用的是此content-type
1 | POST /some-path HTTP/1.1 |
content-type:application/json上传数据可以更多样,可以直接传递数组,对象{ "foo" : "bar", "name" : "John",goods:['fish','beef'] }
后台处理
对于 Request Payload 请求, 必须加@RequestBody
才能将请求正文解析到对应的 bean 中,且只能通过 request.getReader() 来获取请求正文内容
1 | @PostMapping("/accounts") |
- FormData
常见的content-type一般都是application/x-www-form-urlencoded,这是jQuery默认的content-type
对应application/x-www-form-urlencoded:正文请求类似get url请求
1 | POST /some-path HTTP/1.1 |
后台处理
对于 Form Data 请求,无需任何注解,springmvc 会自动使用 MessageConverter 将请求参数解析到对应的 bean,且通过 request.getParameter(…) 能获取请求参数
1 | @PostMapping("/accounts") |
前端可以通过qs来将request payload转为form data上送
1 | import 'Qs'; |
Qs.stringify和JSON.stringify的区别
1 | Qs.stringify( {name:'hehe',age:10})=> name=hehe&age=10 |
上传文件
需要在header中设置{ 'Content-Type': 'multipart/form-data' }
1 | POST /some-path HTTP/1.1 |
调用示例:
1 | const formData = new FormData(); |
DELETE的使用
可以看到axios中传参config中可以使用data和params
1 | // `params` are the URL parameters to be sent with the request |
浏览器中显示
1 | POST /some-path HTTP/1.1 |
GET请求对应Query String Parameters,是没有对应的Content-type的
或对应Content-type:text/plain
在request body中传递是对应Request Payload或FormData
支持CSRF攻击
1 | // 设置CSRFToken |
关于urlencode
前文提到FormData对应的Content-type为application/x-www-form-urlencoded以及GET请求对应的Query String Parameters,此类请求中上送参数都会被浏览器自动encode后上送
但是需要注意的是有时候浏览器encode的并不是我们想要的,比如下面这个陈年老坑
https://mi.com?id=1+2+3
实际后台收到的参数是id=1 2 3,上送时+变成了空格,所以需要前端encodeURIComponent('1+2+3')=>1%2B2%2B3
再上送
实际上会encode成https://mi.com?id=1 2 3,参数还是id=1 2 3
总之遇上+号时,前端最好encodeURIComponent后上送