学学axios

axios现在很火,本人觉得用的人比Ajax多一些,现在都用框架开发,而且使用Ajax要安装jQuery,好像有个人单独抽离出来,从来没用过,所以导致axios现在用的很多,今天随便学一些。
axios基于promise的HTTP库,能设置请求和相应拦截,可以处理请求和响应数据,内部好像还支持防御CSRF跨站请求伪造攻击,浏览器和nodejs都可以使用,使用方法的API就不多说介绍了,可以去看看文档:
http://www.axios-js.com/zh-cn/docs/
先说说浏览器和nodejs环境的判断,主要在下面的方法里面,也叫适配器:

function getDefaultAdapter() {
  var adapter;
  if (typeof XMLHttpRequest !== 'undefined') {
    // For browsers use XHR adapter
    adapter = __webpack_require__(12);
  } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
    // For node use HTTP adapter
    adapter = __webpack_require__(12);
  }
  return adapter;
}

其实蛮简单的,判断对象是否能使用,然后适配器adapter就导入对应的对象。一般我们用的是默认的,axios允许自定义,提供了adapter参数:

// `adapter` 允许自定义处理请求,以使测试更轻松
  // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
  adapter: function (config) {
    /* ... */
  },

如果用了自定义的适配器,就是走自己的方法,返回的是自定义的内容,网上那些自定义适配器的,我都试了一下,没什么意义,有些直接都是走不通,一般我们也不会自定义适配器,只是了解一下,说不定哪天真的需要就要好好研究:

function myAdapter(config) {
    return new Promise((resolve, reject) => {
        resolve({
            a: 20,
            data: {}
        })
    });
}
axios.defaults.adapter = myAdapter;

axios.get('').then(res => {
    console.log(res)
})

axios的请求和响应拦截是使用的核心,其实就是发起请求之前和拿到响应之后的处理,如果我们自己写一个XMLHttpRequest,我们也很容易处理,只不过我们用起来有点类似发布订阅,先看看两个方法,相当于注册了:

this.interceptors = {
  request: new InterceptorManager(),
  response: new InterceptorManager()
};

function InterceptorManager() {
  this.handlers = [];
}
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
  this.handlers.push({
    fulfilled: fulfilled,
    rejected: rejected
  });
  return this.handlers.length - 1;
};

调用:
var chain = [dispatchRequest, undefined];

this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
  chain.unshift(interceptor.fulfilled, interceptor.rejected);
});

this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
  chain.push(interceptor.fulfilled, interceptor.rejected);
});

while (chain.length) {
  promise = promise.then(chain.shift(), chain.shift());
}

循环数组调用之前注册的请求拦截和响应拦截。

至于其他的api,其实都是XMLHttpRequest内部支持的,比如:
设置超时:XMLHttpRequest.timeout
设置header:XMLHttpRequest.setRequestHeader()
允许携带cookie:XMLHttpRequest.withCredentials
上传进度:XMLHttpRequest.upload

这边提一嘴,axios自带的提供了CSRF攻击的防御,从来没用过,也不知道怎么测试有没有效果:

// `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
  xsrfCookieName: 'XSRF-TOKEN', // default

  // `xsrfHeaderName` is the name of the http header that carries the xsrf token value
  xsrfHeaderName: 'X-XSRF-TOKEN', // default

一直没用过取消请求,这其实也是XMLHttpRequest内置方法:
XMLHttpRequest.abort()

我写了一个接口,延迟三秒返回:

const http=require('http');
http.createServer(function(requset,response){
 setTimeout(() => {
  response.end('{a: 10}');
 }, 3000)
}).listen(3001);

然后延时两秒终止:

const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('http://192.168.2.132:3001/', {
    cancelToken: source.token
}).then(res => {
    console.log(res.data)
})
setTimeout(() => {
    source.cancel()
}, 2000)

可以源码内部搜索request.abort();
还有一个点,公司现在项目接口是restful规范,所以之前调用接口,除了get方法,另外的参数不能拼接到地址上面,当时没注意,有些用data传参,有些用params传参,params传参的都会拼接到地址上面。
其实有时候想想看一看这些内部的代码好像没什么意义,因为记不下来,实现的设计模式和思想也是看过就忘了,就当作自己做点无意义的学习吧。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值