axios设置content-type

15,036 阅读3分钟

用axios总觉得莫名的这个那个出错,就简单的总结了下。

cdn的地址https://unpkg.com/axios@0.19.0/dist/axios.min.js,版本号可以更换,没有版本号就是最新发布的。
不过,当前这年头,很多时候npm i axios即可。

关键使用axios的步骤:

  1. 创建axios的实例,这样能将公共配置放在这里,如instance.js,处理各种异常情况
  2. 每个api单独写好,多的话写个文件夹,相关的api可以写在一个文件里,少的话直接一个文件如api.js
  3. 将api放在全局,这样使用的时候,无需引入,页面调接口的时候直接 this.api.apiName()

必须先理解content-type

get请求不存在设置content-type。只有post和put用到content-type,常用的post方式,所以这里着重说post。
post的content-type三种类型:

  • Content-Type: application/json
    对于axios,post的时候axios.post(url,{a:1,b:2}),第二个参数是对象的时候,默认是这个类型

  • Content-Type: application/x-www-form-urlencoded
    对于axios,post的时候let data = {a:1,b:2}; axios.post(url,qs.stringify({ data })),第二个参数是字符串的时候,默认是这个类型

  • Content-Type: multipart/form-data
    对于axios,post的时候let data = new FormData(); data.append('a',1'); data.append('b',2); axios.post(url,data),参数是formData类型的时候,默认是这个类型,如果用form自带的action提交,默认是这个类型

以上三种方式,服务器会以不同的方式解析,这点尤其注意!!!!!

换言之,content-type会根据参数的类型会自动有对应的值,一般无需设置~~~
但是,有些情况是,我想传对象,但实际服务器需要的的是application/x-www-form-urlencoded,此时需要只需要统一设置请求前将参数变成字符串即可transformRequest: [ function (data) { return Qs.stringify(data) } ],

此处小结,上面的解释多看几遍,我反射弧长,很久才大约明白到底说的啥。

创建axios的实例

以下是示例代码。

/**
 * axios封装
 * 请求拦截、响应拦截、错误统一处理
 */
import axios from 'axios';

// 创建axios实例
var instance = axios.create({    timeout: 1000 * 12});
/** 
 * 请求拦截器 
 * 每次请求前,如果存在token则在请求头中携带token 
 */ 
instance.interceptors.request.use(    
    config => {        
        // 这里可以加统一的参数,appid,token这类的
    },    
    error => Promise.error(error)
)

// 响应拦截器
instance.interceptors.response.use(    
    // 请求成功
    res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),    
    // 请求失败
    error => {
        const { response } = error;
        if (response) {
            // 请求已发出,但是不在2xx的范围,一般会和后台确定一些错误码,处理错误
            errorHandle(response.status, response.data.message);
            return Promise.reject(response);
        } else {
            // 请求都没发出去
            // 处理断网的情况
            if (!window.navigator.onLine) {
               // 断网做啥
            } 
            return Promise.reject(error);
        }
    }
);

export default instance;

每个api单独写好

// api.js
// 以对象的形式传参,这样参数不需要考虑顺序的问题
const ajaxKeMuData = ({ wind, projectSname = "" }) =>
  instance.post('/keMuXuBanRate', {
    wind,
    projectSname
  });
export {
    ajaxKeMuData
}

将api放在全局

最后统一加在全局里,这边如果是vue的项目

// main.js
import api from './api' // 导入api接口
Vue.prototype.$api = api; // 将api挂载到vue的原型上

页面里调用的时候this.$api.ajaxKeMuData({...}).then(...)

最后

这边写的很粗略,也还有些需要完善,很多细节请看axios的好文章,特别是更新处

axios的好文章,特别是更新处
content-type的解释