axios

基本使用

axios({
    method: 'get',   // get,获取数据;post,提交数据(表单提交以及文件上传);put,更新数据 (提交所有的数据);patch,提交数据 (提交修改的数据);delete,删除数据
    url: '',
    params: {}
}).then(res => { do something })

并发请求

同时进行多个请求,并统一处理返回值,如果在某些场景中我们需要同时依赖两个接口返回的数据,那么我们可以使用并发请求:

axios.all([  // 这里的参数是一个数组,里面包含了axios请求
  axios.get('url1'), // 请求的先后顺序就是代码中的顺序
  axios.get('url2')
]).then(
  axios.spread((res1, res2) => { // spread用来分割返回值
    console.log(res1, res2)
  }
).catch(err => {
    console.log(err)
})

请求拦截器

例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易

axios.interceptors.request.use(
  config => {}, // 在发送请求前的一些处理逻辑
  err => {} // 在请求错误后的处理
)

响应拦截器

例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页

axios.interceptors.response.use(
  res => { return res }, // 请求成功后对响应数据做一定的处理
  err => { return Promis.reject(err)} // 在响应错误后的处理,可以用catch捕捉
)

axios取消http请求

let api = axios.create({})  // 实例化axios
let source = axios.CancelToken.source() // 实例化一个source对象

api.get('/data.json', { 
    cancelToken: source.token // 请求时携带cancleToken
}).then(callback).catch(err => {
    console.log(err)
})

source.cancel('message') // 调用source的cancel方法取消http请求,并将message以error的形式返回,然后就取消了http请求,并进入到该请求的catch代码块,进行错误处理。

 设置全局的默认行为

axios.defaults.timeout = 30000;   // 设置超时时间30秒
axios.defaults.validateStatus= status => ((status >= 200 && status < 300) || status == 401);   //设置 200-300 和 401 都返回成功

axios的特点有哪些?

一、Axios 是一个基于 promise 的 HTTP 库,支持promise所有的API;
二、它可以拦截请求和响应;
三、它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据;
四、安全性更高,客户端支持防御 XSRF;

原理

判断环境

function getDefaultAdapter() {
 var adapter;
 if (typeof XMLHttpRequest !== ‘undefined‘) {
   //通过判断XMLHttpRequest是否存在,来判断是否是浏览器环境
   adapter = require(‘./adapters/xhr‘);
 } else if (typeof process !== ‘undefined‘) {
   //通过判断process是否存在,来判断是否是node环境
   adapter = require(‘./adapters/http‘);
 }
 return adapter;
}

拦截器

他是axios的一大特色,它的实现原理其实不复杂,核心就是promise的链式调用

/**
* 处理一个请求
*
* @param config 请求的配置
*/

Axios.prototype.request = function request(config) {
 // 如果是字符串,则直接赋值给配置的url属性
 if (typeof config === ‘string‘) {
   config = utils.merge({
     url: arguments[0]
   }, arguments[1]);
 }
 // 合并默认配置和配置参数    
 config = utils.merge(defaults, this.defaults, { method: ‘get‘ }, config);
 config.method = config.method.toLowerCase();
 // 连接拦截器中间件
 var chain = [dispatchRequest, undefined];
 var promise = Promise.resolve(config);
 //依次在处理链路数组中,从头部添加请求拦截器中间件
 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());
 }
 //返回promise对象
 return promise;
}

定义了一个chain数组,同时放入了dispatchRequest, undefined这两个元素对应promise的resolve和reject方法,之后将请求拦截器的成功和失败处理依次压入chain数组头部,将返回拦截器的成功和失败处理依次推入chain数组尾部。 最后循环取出chain数组,先依次取出chain数组中成对的请求拦截处理方法,promise执行,然后取出最初定义的dispatchRequest, undefined这两个元素执行请求,最后依次取出chain数组中成对的响应拦截器。

自动转换JSON数据

// 转换返回的数据
response.data = transformData(
 response.data,
 response.headers,
 config.transformResponse
);

axios通过设置transformResponse,可自动转换请求返回的json数据
transformResponse: [function transformResponse(data) {
   /*eslint no-param-reassign:0*/
   if (typeof data === ‘string‘) {
       try {
       data = JSON.parse(data);
       } catch (e) { /* Ignore */ }
   }
   return data;
}],

 axios.all其实就是调用Promise.all

取消请求

if (config.cancelToken) {
 // 处理取消请求的方法
 config.cancelToken.promise.then(function onCanceled(cancel) {
   if (!request) {
     return;
   }
   // XMLHttpRequest.abort() 方法将终止请求,如果该请求已被发出
   request.abort();   
   reject(cancel);
   // 清空请求
   request = null;
 });

}

在请求时如果设置了cancelToken参数,就会监听来自cancelToken的promise,一旦来自cancelToken的promise被触发,就会执行取消请求的流程

cancelToken的具体实现为:

function CancelToken(executor) {
 //判断executor是一个可执行的函数
 if (typeof executor !== ‘function‘) {
   throw new TypeError(‘executor must be a function.‘);
 }
 //定义一个promise的resolve回调
 var resolvePromise;
 this.promise = new Promise(function promiseExecutor(resolve) {
   resolvePromise = resolve;
 });
 var token = this;
 //executor的参数为取消请求时需要执行的cancel函数
 executor(function cancel(message) {
   if (token.reason) {
     // 已经取消了请求
     return;
   }
   token.reason = new Cancel(message);
   //触发promise的resolve
   resolvePromise(token.reason);
 });

}

就是在上面的代码里,CancelToken会给自己添加一个promise属性,一旦cancel方法被触发就会执行取消请求的流程。

利用这个方法,一方面可以在按钮的重复点击方面大显身手,另一方面可以在数据的获取方面直接获取最新的数据。

客户端防止xsrf攻击

设置token

原文:https://www.jianshu.com/p/a94a94618c78

https://blog.csdn.net/mmjinglin/article/details/82761126

原文地址:https://www.cnblogs.com/xjy20170907/p/12742405.html