Problem scenario
The scenario is simple, just a normal AXIos POST request:
axios({
headers: {
'deviceCode': 'A95ZEF1-47B5-AC90BF3'
},
method: 'post',
url: '/api/lockServer/search',
data: {
username,
pwd}})Copy the code
The background says it did not receive your parameter.
This is a little strange, I looked at the browser request message is OK, the parameters are all there, and before using Axios there was no problem.
But this interface is universal, other people use, is OK, the interface is OK.
Question why
The point 1
The reason is that this time the interface uses Java Spring MVC and uses the @requestParam annotation on this method
Username =admin&password=admin; username=admin&password=admin;
The point 2
We can also see the content-Type of our request:
application/json; charset=UTF-8Copy the code
A few things to say about this:
Axios will help us convert request and response data and automatically convert JSON data
2. Find the following in axios source code :(critical)
We know that when we make a POST request, our pass parameter isdata: {... }
Or directly{... }
In the form of, well, these are the following two forms
【 Form 1 】
【 Second form 】
Very excitingly, both of these forms trigger the [critical] section of axios’s source code
Problem analysis
That is, our Content-Type becomes application/json; Charset = UTF-8 Then, since our argument is a JSON object, Axios does a stringify for us. And a look at the AXIos documentation shows that when AXIos sends data using POST, the default is to put JSON directly into the request body and submit it to the back end.
So this doesn’t match our server requirements of ‘Content-Type’: ‘application/ X-www-form-urlencoded ‘and @requestParam.
The solution
Solution 1
Pass parameters with URLSearchParams
let param = new URLSearchParams()
param.append('username'.'admin')
param.append('pwd'.'admin')
axios({
method: 'post',
url: '/api/lockServer/search',
data: param
})Copy the code
Note that URLSearchParams does not support all browsers, but the overall support is OK, so this straightforward solution is preferred
Solution 2
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
{headers:{'Content-Type':'application/x-www-form-urlencoded'}}
import Qs from 'qs'
let data = {
"username": "admin"."pwd": "admin"
}
axios({
headers: {
'deviceCode': 'A95ZEF1-47B5-AC90BF3'
},
method: 'post',
url: '/api/lockServer/search',
data: Qs.stringify(data)
})Copy the code
Solution 3
Since axios has a key piece of code in the source code, we can also modify the transformRequest to achieve this.
In the axios request configuration item, yestransformRequest
Of the configuration of:
OK, so now our request can be written like this:
import Qs from 'qs'
axios({
url: '/api/lockServer/search',
method: 'post',
transformRequest: [function(data) {// Perform any conversion on datareturn Qs.stringify(data)
}],
headers: {
'deviceCode': 'A95ZEF1-47B5-AC90BF3'
},
data: {
username: 'admin'.pwd: 'admin'}})Copy the code
Solution 4
[Rewrite an Axios instance to re-implement our own transformRequest]
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');
returndata.toString(); } /* Change this */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('&'));
}
returndata; }],})Copy the code
Solution 5
axios.post('/api/lockServer/search'."userName='admin'&pwd='admin'");Copy the code