理解---axios------从此走上人生巅峰

axios

安装axios
npm install axios --save
引用
直接script标签引用
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

也可以去GitHub上去观看原工程文件

https://github.com/axios/axios

使用


发送一个最简单的请求

这里我们发送一个带参数的get请求,params参数放在get方法的第二个参数中,如果没有参数get方法里可以只写路径。如果请求失败捕获一下异常。

axios
  .get('/list',{
      params: {
         id: 5
      }
   })
  .then(res => {
    console.log('数据是:', res);
  })
  .catch((e) => {
    console.log('获取数据失败');
  });

当然,我们也可以发送一个POST请求,post方法的第二个参数为请求参数对象。

this.$axios.post('list',{
  name: '小刘'
})
.then(function(res){
  console.log(res);
})
.catch(function(err){
  console.log(err);
});
一次合并发送多个请求

分别写两个请求函数,利用axios的all方法接收一个由每个请求函数组成的数组,可以一次性发送多个请求,如果全部请求成功,在axios.spread方法接收一个回调函数,该函数的参数就是每个请求返回的结果。

function getUserAccount(){
  return axios.get('/user/12345');
}
function getUserPermissions(){
  return axios.get('/user/12345/permissions');
}
this.$axios.all([getUserAccount(),getUserPermissions()])
  .then(axios.spread(function(res1,res2){
    //当这两个请求都完成的时候会触发这个函数,两个参数分别代表返回的结果
}))
axios的API

以上通过axios直接调用发放来发起对应的请求其实是axios为了方便起见给不同的请求提供的别名方法。我们完全可以通过调用axios的API,传递一个配置对象来发起请求。

发送post请求,参数写在data属性中

axios({
  url: 'list',
  method: 'post',
  data: {
    name: '小刘'
  }
}).then(res => {
  console.log('请求结果:', res);
});

发送get请求,默认就是get请求,直接第一个参数写路径,第二个参数写配置对象,参数通过params属性设置。

axios('list', {
  params: {
    name: '小刘'
  }
}).then(res => {
  console.log('请求结果:', res);
});

axios为所有请求方式都提供了别名:

  • axios.request(config)
  • axios.get(url, [config])
  • axios.delete(url, [config])
  • axios.head(url, [config])
  • axios.options(url, [config])
  • axios.post(url, [data], [config])
  • axios.put(url, [data], [config])
  • axios.patch(url, [data], [config])
axios配置默认值

1、可以通过axios.defaults设置全局默认值,在所有请求中都生效。

axios.defaults.headers.common["token"] = ""
axios.defaults.headers.post["Content-type"] = "application/json"
axios.defaults.baseURL = 'https://service.xxx.com; //设置统一路径前缀

2、也可以自定义实例的默认值,以及修改实例的配置

// 创建时自定义默认配置,超时设置为全局默认值0秒
let ax = axios.create({
  baseURL: 'http://123456.com',
  params: { name: 'liu' }
});
// 修改配置后,超时设置为4秒
ax.defaults.timeout = 4000; 

3、也可以像前面那样,在每个请求中设置相关的配置。

axios('/app', {
  params: {
    name: 'liu'
  },
  baseURL: 'http://123456.com'
})
{
    method:'请求方法',
    baseURL:'如果路径不是绝对路径,就会在路径前自动添加此路径',
    transformRequest: [(data, header)=>{}], //在发送请求之前修改数据,适用于post、put、patch
    transformResponse:  [(data)=>{
        return JSON.parse(data).data;
    }], //在收到的数据传到then之前修改数据,注意这里data是个字符串类型。
    header: {'X-Requested-With': 'XMLHttpRequest'}, //请求头
    params: {}, //请求参数
    paramsSerializer: (params)=>{
        return qs.stringify(params); //name=xiaohong&id=1
    } //可选函数,可以把参数拼接成字符串
    data: {}, // post类方法的请求体参数
    timeout: 0, //请求延时事件,如果超时请求终止
    withCredentials: false, //是否时跨站点请求
    onUploadProgress: (progressEvent)=>{
        //可以通过progressEvent拿到上传的进度
    },
    onDownloadProgress: ()=>{},//和onUploadProgress一样,获取下载的进度
    responseType: json,  // 返回的数据格式
    maxContentLength: 2000, //相应内容的最大尺寸
    validateStatus: (validateStatus)=>{
        return validateStatus >= 200; //限制相应状态码,如果不满足就拒绝
    },
    cancelToken: new cancelToken(function(cancel){}) // 指定一个取消请求标识,下面会用到
}
拦截器

可以分别设置请求拦截和响应拦截,在发出请求和响应到达then之前进行判断处理。

  //添加一个请求拦截器
        axios.interceptors.request.use(function(config){
        //在请求发出之前进行一些操作
        return config;
        },function(err){
        //Do something with request error
        return Promise.reject(error);
        });


        
        //添加一个响应拦截器
        axios.interceptors.response.use(function(res){
        //在这里对返回的数据进行处理
        return res;
        },function(err){
        //Do something with response error
        return Promise.reject(error);
        })

以上以相应拦截器为例,请求拦截器同样,只是把response换成request。第一个参数是成功回调,第二个是错误回调。
也可以移除拦截器,就像移除js定时器一样的操作:

var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

跨域配置


如果我们要跨域请求数据,在配置文件里设置代理,vue-cli3项目,需要在根目录自己创建一个vue.config.js,在里面写配置。

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'https://www.xxx.com', //目标路径,别忘了加http和端口号
        changeOrigin: true, //是否跨域
        ws: true,
        pathRewrite: {
          '^/api': '' //重写路径
        }
      }
    }
  }
};

调用接口:

axios.post('/api/test', {name: 'xiao'}); 

如果没有重写路径,访问的就是https://www.xxx.com/api/test,如果像上面代码那样重写路径访问的就是https://www.xxx.com/test

原理:

因为客户端请求服务端的数据是存在跨域问题的,而服务器和服务器之间可以相互请求数据,是没有跨域的概念(如果服务器没有设置禁止跨域的权限问题)

使用Promise封装自己的Ajax库

// const axios = require("../axios/axios");

;(function anonymous(window){
    // 设置默认配置项
    let _default = {
        method: "GET",
        url : "",
        baseURL : "",
        headers : {},
        dataType : "JSON",
        data:null,     //=》post系列请求基于问号传参传递给服务器的内容
        params : null,  //=> get系列请求基于问号传参传递给服务器的内容,
        cache : true
    }


    // 基于promise设计模式管理AJAX请求
    let ajaxPromise = function ajaxPromise(options){
        // options中融合了:默认配置信息,基于用户defaults修改的信息,用户执行get/post配置请求时,越靠后优先级越高
        let {
            url,baseURL,method,data,dataType,headers,cache,params
        } = options;

        //把传递的参数进一步处理
        if(/^(GET|DELETE|HEAD|OPTIONS)$/i.test(method)){
            // GET系列
            if(params){
                url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`
            }
            if(cache === false){
                url += `${ajaxPromise.check(url)}_=${+(new Date())}`
            }
            data = null  //=>GET系列请求主体就是什么都不放
        }else{
            //  POST系列
            if(data){
                data = ajaxPromise.formatData(data)
            }
        }

        // 基于promise发送Ajax
        return new Promise((resolve,reject)=>{
            let xhr = new XMLHttpRequest
            xhr.open(method,`${baseURL}${url}`)
            //=>如果出现headers 就要设置请求头
            if(headers !==null && typeof headers === "object"){
                for (let attr in headers){
                    if (headers.hasOwnProperty(attr)){
                        let val = headers[attr]
                        if(/[\u4e00-\u9fa5]/.test(val)){
                            //val中包含中文  我们进行编码encodeURLComponent/decodeURLComponent
                            val = encodeURIComponent(val)
                        }
                        xhr.setRequestHeader(attr,headers[attr])
                    }
                }
            }
            xhr.onreadystatechange = () =>{
                if(xhr.readyState ===4){
                    if(/^(2|3)\d{2}$/.test(xhr.status)){
                        let result = xhr.responseText
                        dataType = dataType.toUpperCase()
                        dataType === 'JSON' ? result = JSON.parse(result) : (dataType === 'XML' ? result = xhr.responseXML :null)
                        resolve(result,xhr)
                        return;
                    }
                    reject(xhr.statusText,xhr);
                }
            }
            xhr.send(data)
        })
    };

     // 把对象转化为URLENCODE格式的字符串
    ajaxPromise.formatData = function formatData(obj){
        let str = "";
        for (let attr in obj){
            if(obj.hasOwnProperty(attr)){
                str += `${attr}=${obj[attr]}&`
            }
        }
        return str.substring(0,str.length - 1)
    }
    ajaxPromise.check = function check(url){
        return url.indexOf('?') > -1 ? '&' : '?';
    };

    // =>GET
    ['get','delete','head','options'].forEach(item=>{
        ajaxPromise[item] = function anonymous(url,options = {}){
            options = {
                ..._default,    //默认值或者基于defaults修改的值
                ...options,          //用户调取方法传递的配置项
                url : url,               //请求的url的地址(第一个参数:默认配置项和传递的配置项中对不会出现url,只能这样获取)
                method : item.toUpperCase()   ///以后执行肯定是ajaxPromise.head执行,不会设置methods这个配置项,我们自己需要配置才可以
            }
            return ajaxPromise(options)
        }
    });

    // post 
    ['post','put','patch'].forEach(item=>{
        ajaxPromise[item] = function anonymous(url,data={},options = {}){
            options = {
                ..._default,   
                ...options,         
                url : url,              
                method : item.toUpperCase(),   
                data : data
            }
            return ajaxPromise(options)
        }
    });

    ajaxPromise.get = function (url,options){

    };
    ajaxPromise.post = function (url,data,options){

    };

    //把默认配置暴漏出去
    ajaxPromise.defaults = _default
    window.ajaxPromise = ajaxPromise;
})(window)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值