Problem Scenario
The scenario is simple, which is a normal Axios POST request:
axios({ headers: { ‘deviceCode‘: ‘A95ZEF1-47B5-AC90BF3‘ }, method: ‘post‘, url: ‘/api/lockServer/search‘, data: { username, pwd }})
Backstage said not received your communication.
This is a bit strange, I looked at the browser request information is OK, parameters are there, and before this with Axios also does not have this problem.
But this interface is universal, others use, is OK, interface no problem.
The cause of the problem point 1
The reason for this is that the interface uses Java Spring MVC
and used annotations on this method.@RequestParam
So what does this mean, that this is the only parameter that can be extracted from the requested address, that is, the argument can only be username=admin&password=admin
parsed from this string.
Point 2
We can also see the content-type of our request:
application/json;charset=UTF-8
In this regard, it is important to note that:
1. Axios will help us transform the request and response data and automatically convert the JSON data
2, in the Axios source found the following paragraph:(very key)
We know that when we do a POST request, our arguments are data: {...}
passed in direct {...}
form, well, the following two forms
"The first form of"
"Second Form"
Very exciting, both forms without exception triggered the "very critical" piece of code in the Axios source
Problem analysis
That is to say, we Content-Type
have application/json;charset=utf-8
become
Then, because our parameters are JSON objects, Axios helps us do a stringify processing.
and consult the Axios documentation to know: Axios when using post to send data, the default is to directly put the JSON into the request body submitted to the backend.
Well, this is not in line with what our server requires ‘Content-Type‘: ‘application/x-www-form-urlencoded‘
and @RequestParam
does not.
Solution Solution One
"Passing Parameters with Urlsearchparams"
param = new URLSearchParams()param.append(‘username‘, ‘admin‘)param.append(‘pwd‘, ‘admin‘)axios({ method: ‘post‘, url: ‘/api/lockServer/search‘, data: param})
It is important to note that URLSearchParams
all browsers are not supported, but the overall support is OK, so it is preferable to recommend this simple and straightforward solution.
Solution II
There are many programs on the Internet that use
axios.defaults.headers.post[‘Content-Type‘] = ‘application/x-www-form-urlencoded‘;
Or
{headers:{‘Content-Type‘:‘application/x-www-form-urlencoded‘}}
I tried it, but it's still not working.
"Additional action is required(we want to convert the parameter to the query parameter)"
The introduction of QS, this library is included in the Axios, do not need to download again.
from ‘qs‘let data = { "username": "admin", "pwd": "admin"}axios({ headers: { ‘deviceCode‘: ‘A95ZEF1-47B5-AC90BF3‘ }, method: ‘post‘, url: ‘/api/lockServer/search‘, data: Qs.stringify(data)})
Solution Three
Since Axios source has a "very critical" code, then we can also modify transformRequest
to achieve our goal.
In the Axios request configuration item, there is a transformRequest
configuration:
OK, so now our request can be written in the following way:
‘qs‘axios({ url: ‘/api/lockServer/search‘, method: ‘post‘, transformRequest: [function (data) { // 对 data 进行任意转换处理 return Qs.stringify(data) }], headers: { ‘deviceCode‘: ‘A95ZEF1-47B5-AC90BF3‘ }, data: { username: ‘admin‘, pwd: ‘admin‘ }})
Solution IV
"Rewrite a Axios instance and 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)) {ReturnData }if (utils. Isarraybufferview (Data)) {ReturnData. Buffer; }if (utils. Isurlsearchparams (Data) {Setcontenttypeifunset (headers,' Application/x-www-form-urlencoded;charset=utf-8 ');ReturnData. toString (); }/ * Change here */ if (utilsisobject (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; ],})
Solution Five
axios.post(‘/api/lockServer/search‘,"userName=‘admin‘&pwd=‘admin‘");
Solution VI
We know now that our service-side students receive parameters @RequestParam
(by parsing parameters in a string)
In fact, there is another way @RequestBody
(get parameters from the request body).
We let the back end of the classmate to change @RequestBody
it, (#^.^#), "he said I do not change it."
Axios POST request, the backend does not receive the parameters of the solution