接收一个axios
发送的post
请求,结果数据死活接收不到,请求头也正常,请求头设置Content-type
也同样不好使,下面详细分析下问题出在哪儿了。
问题场景
代码很简单,跟示例一样。
1 2 3 4 5 6 7 8 9 10
| axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
|
后端使用php接收,get没问题,post一直为空。
问题原因
我们从请求头中可以看出, Content-Type
变成了 application/json;charset=utf-8
然后,因为我们的参数是 JSON 对象,axios 帮我们做了一个 stringify 的处理。
而且查阅 axios 文档可以知道:axios 使用 post 发送数据时,默认是直接把 json 放到请求体中提交到后端的。
那么,这就与我们服务端要求的 'Content-Type': 'application/x-www-form-urlencoded'
以及 @RequestParam
不符合。
解决方案
URLSearchParams传递参数
1 2 3 4 5 6 7 8 9 10
| let data = new URLSearchParams() data.append('firstName': 'Fred') data.append('lastName': 'Flintstone') axios.post('/user', data) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
|
需要注意的是: URLSearchParams
不支持所有的浏览器,但是总体的支持情况还是 OK 的,所以优先推荐这种简单直接的解决方案
qs库
网上有很多方案说使用
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
或者
{headers:{'Content-Type':'application/x-www-form-urlencoded'}}
我试了一下,其实这样还是不行的
【还需要额外的操作,(我们要将参数转换为query参数)】
引入 qs ,这个库是 axios 里面包含的,不需要再下载了。
1 2 3 4 5 6 7 8 9 10
| import Qs from 'qs'
let data = {'firstName': 'Fred','lastName': 'Flintstone'} axios.post('/user', Qs.stringify(data)) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
|
既然 axios 源码中有那么一段【很关键】的代码,那么,我们也可以通过修改 transformRequest
来达到我们的目的。
在 axios 的请求配置项中,是有 transformRequest
的配置的:
1 2 3 4 5 6 7 8 9
| transformRequest: [function (data) {
return data; }],
|
OK,那么现在我们的请求就可以写成下面这个样子了:
1 2 3 4 5 6 7 8 9 10 11
| import Qs from 'qs' let data = {firstName: 'Fred',lastName: 'Flintstone'} axios({ url: '/user', method: 'post', transformRequest: [function (data) { return Qs.stringify(data) }], data: data })
|
重写axios
【重写一个 axios 实例,重新实现属于我们自己的 transformRequest】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import axios from 'axios' let instance = axios.create({ transformRequest: [function transformRequest(data, headers) { normalizeHeaderName(headers, 'Content-Type'); if (utils.isFormData(data) || utils.isArrayBuffer(data) || utils.isBuffer(data) || utils.isStream(data) || utils.isFile(data) || utils.isBlob(data) ) { return data; } if (utils.isArrayBufferView(data)) { return data.buffer; } if (utils.isURLSearchParams(data)) { setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); return data.toString(); } if (utils.isObject(data)) { setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); let _data = Object.keys(data) return encodeURI(_data.map(name => `${name}=${data[name]}`).join('&')); } return data; }], })
|
类似get传参
1
| axios.post('/user',"firstName='Fred'&lastName='Flintstone'");
|