axios 默认是 Payload 格式数据请求, 但有时候后端接收参数要求必须是 Form Data 格式的, 所以我们就得进行转换.
Payload 和 Form Data 的主要设置是根据请求头的 Content-Type 的值来的.
一、 设置单个的 POST 请求为 Form Data 格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | axios({   method: 'post',   url: 'http://localhost:8080/login',   data: {     username: this.loginForm.username,     password: this.loginForm.password   },   transformRequest: [     function(data) {       let ret = ''       for (let it in data) {                  ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'       }       ret = ret.substring(0, ret.lastIndexOf('&'))       return ret     }   ],   headers: {     'Content-Type': 'application/x-www-form-urlencoded'   } })
  | 
 
方法二: 利用 URLSearchParams, 不兼容 IE, 貌似安卓 / iOS 低版本也不兼容
1 2 3 4 5 6 7 8
   | const params = new URLSearchParams() params.append('username', this.loginForm.username) params.append('password', this.loginForm.password) axios({   method: 'post',   url: 'http://localhost:8080/login',   data: params })
   | 
 
1 2 3 4 5 6 7 8
   | const params = new FormData() params.append('username', this.loginForm.username) params.append('password', this.loginForm.password) axios({   method: 'post',   url: 'http://localhost:8080/login',   data: params })
   | 
 
方法四: 利用 qs
1 2 3 4 5 6 7 8 9
   | const params = {   username: this.loginForm.username,   password: this.loginForm.password } axios({   method: 'post',   url: 'http://localhost:8080/login',   data: qs.stringify(params) })
  | 
 
二、 全局设置 POST 请求为 Form Data 格式
因为像上面那样每个请求都要配置 transformRequest 和 Content-Type 非常的麻烦, 重复性代码也很丑陋, 所以通常都会进行全局设置. 具体代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | import axios from 'axios' import qs from 'qs'
 
  let instance = axios.create({   timeout: 6000,   headers: {     'Content-Type': 'application/x-www-form-urlencoded'   } })
 
  instance.interceptors.request.use(   config => {     config.data = qs.stringify(config.data)      return config   },   error => Promise.error(error) )
   | 
 
就是我们在封装 axios 的时候, 设置请求头 Content-Type 为   application/x-www-form-urlencoded . 然后在请求拦截器中, 通过 qs.stringify() 进行数据格式转换, 这样每次发送的 POST 请求都是 Form Data 格式的数据了. 其中 qs 模块是安装 axios 模块的时候就有的, 不用另行安装, 通过 import 引入即可使用.
上面的方法会将全部 post 请求都转换成 Form Data 格式了, 实际上并不是所有请求都是这样的. 我们可以根据一个参数判断是否需要转换
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
   | import axios from 'axios' import qs from 'qs' import { Message, Loading } from 'element-ui'
 
 
 
 
 
 
 
  export const $post = (url, params, type, isLoading = true) => {   if (isLoading) {     var loadingInstance = Loading.service({       text: '正在加载中'     })   }   type === 'form' && params = qs.stringify(params)   return new Promise((resolve, reject) => {     axios       .post(url, params, {})       .then(res => {         if (isLoading) {           loadingInstance.close()         }         if (res.status === 200) {           if (res.data.code === 0) {             resolve(res.data)           } else if (res.data.code === 401) {             failMessage(res.data.message)             setTimeout(() => {               window.location.href = '/static/login.html'             }, 2000)             reject(res)           } else {             failMessage(res.data.message)             reject(res)           }         } else {           failMessage()           reject(res)         }       })       .catch(mes => {         if (isLoading) {           loadingInstance.close()         }         if (mes.response.status === 306) {           failMessage('您身份已过期,3秒后返回登录页面')           setTimeout(() => {             window.location.href = '/static/login.html'           }, 3000)           reject(mes)         } else if (mes.response.status === 403) {           failMessage('无访问权限')           reject(mes.response.data)         } else {           failMessage()           reject(mes.response.data)         }       })   }) }
  function failMessage(mes = '数据获取失败') {   Message({     showClose: true,     message: mes,     type: 'warning'   }) }
   |