要做的需求很简单,就是一个axios的简单请求,如下:

axios({
    method: 'post',
    url: '/api/login',
    data: {
        username,
        pwd
    }})

但是问题来了,后端说取不到我的username和pwd,问题又来了,值确实传过去了,但是后端获取不到

原因:后端用的框架是 spring mvc ,并且在这个方法上使用了注解 @RequestParam,这个就只能从请求的地址中取出参数,也就是只能从 username=admin&pwd=11111 这种字符串中解析出参数,也就是编码格式(content-type)为:application/x-www-form-urlencode。(表单form的enctype属性的编码方式有两种:application/x-www-form-urlencode和multipart/form-data),但是axios会把请求的数据转换成json格式,即为:application/json;charset=UTF-8,所以格式不同,就取不到值了。

解决方案我尝试了有6种,大家可以根据自己的需求选择:

  1. ※ 设置Content-Type(推荐)
    (1)axios.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded’; //(推荐)
    或者:{headers:{‘Content-Type’:‘application/x-www-form-urlencoded’}}
    (2)引入 qs (这个库是 axios 里面包含的,直接引入,无需下载)。
import Qs from 'qs'
let data = {
    "username": "admin",
    "pwd": "admin"
};
axios({
    headers: {
        'deviceCode': 'A95ZEF1-47B5-AC90BF3'
    },
    method: 'post',
    url: '/api/login',
    data: Qs.stringify(data)
})
  1. 用 URLSearchParams
let param = new URLSearchParams()param.append('username', 'admin')param.append('pwd', 'admin')
axios({
    method: 'post',
    url: '/api/login',
    data: param
})

缺点:兼容性不太好

  1. 设置transformRequest
    因为我们的请求编码格式是被axios更改的,那我们也可以进去设置,如下:
import Qs from 'qs'
axios({
    url: '/api/login',
    method: 'post',
    transformRequest: [function(data){       
         // 对 data 进行任意转换处理        
        return Qs.stringify(data)
    }],
    headers: {
        'deviceCode': 'A95ZEF1-47B5-AC90BF3'
    },
    data: {
        username: 'admin',
        pwd: 'admin'    
    }
})

4.重写一个 axios 实例,重新实现属于我们自己的 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');
            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;
    }],
})

5.axios.post(’/api/lockServer/search’,“userName=‘admin’&pwd=‘admin’”);

6.我们知道服务端用的是 @RequestParam(通过字符串解析出参数) ,其实还有另一种是 @RequestBody(从请求体中获取参数),让后端改成 @RequestBody也可以。


source:
作者:_kayla
链接: https://www.jianshu.com/p/961a4c97e057
来源:简书
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐