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

There are many programs on the Internet that say use



axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';






{headers:{'Content-Type':'application/x-www-form-urlencoded'}}


I tried, but it still doesn’t work





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, yestransformRequestOf 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