# axios概念

  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

关于aixos的xsrf防御

Axios 客户端支持防御 XSRF 主要通过在客户端与服务端首次登录确认身份成功后,服务端会颁发给客户端一个身份认证令牌。

客户端往往会把这个 token 添加到请求的 headers 中。

服务器端要求每次请求都包含一个 token,这个 token 是在每次访问站点的时候由服务器端生成的,并通过 set-cookie 的方式种到客户端,然后客户端发送请求的时候,从 cookie 中对应的字段读取出 token,然后添加到请求 headers 中。这样服务端就可以从请求 headers 中读取这个 token 并验证。由于这个 token 是很难伪造的,所以就能区分这个请求是否是用户正常发起的。

axios 在默认请求配置对象中提供了 xsrfCookieNamexsrfHeaderName 这两个属性。其中 xsrfCookieName 表示存储 token 的 cookie 的名称,xsrfHeaderName 表示请求 headers 中 token 对应的 header 的名称。然后每次发送请求的时候,会自动从 cookie 中读取对应的 token 值,然后将其添加到请求 headers 中。

xsrfCookieName 和 xsrfHeaderName 这两个属性在axios的配置中默认是没有值的,需要前端自己指定。

一般来说,后端会设置一个cookie,命名为 XSRF-TOKEN,存储XSRF令牌,然后通过HTTP响应头 Set-Cookie 返回给前端。在浏览器中,这个cookie的名字就是 XSRF-TOKEN。

因此,可以在axios的配置中这样设置:

axios.defaults.xsrfCookieName = 'XSRF-TOKEN';  
axios.defaults.xsrfHeaderName = 'X-XSRF-TOKEN';

这样,axios在每次发送请求时,都会自动从cookie中获取名为 XSRF-TOKEN 的cookie的值,然后添加到HTTP请求头 X-XSRF-TOKEN 中。

这里只是为了演示如何设置这两个属性,实际的后端配置可能会有所不同。

# 安装

npm install axios

# 执行GET请求

 // 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// 可选地,上面的请求可以这样做
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

# 执行 POST 请求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

# 执行多个并发请求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }));
this.$axios.all([
		that.$axios.post('/org/findUser1',postData),
		that.$axios.post('/org/findUser2',postData)
	]).then(that.$axios.spread(function (userResp, userResp2) {
		that.inputstr="";
		console.log(userResp.data.data.usrList)
		// 上面两个请求都完成后,才执行这个回调方法
		/*当所有的请求都完成后,会收到一个数组,包含着响应对象,
		其中的顺序和请求发送的顺序相同,可以使用 axios.spread 分割成多个单独的响应对象*/
		if(userResp.data.meta.success==true){
			if(userResp.data.data.usrList){
				 that.searcharr1=userResp.data.data.usrList;
			}else{
				 that.searcharr1=[];
			}		   
		}else{
			that.searcharr1=[];
		}
		if(userResp2.data.meta.success==true){
		   if(userResp2.data.data.usrList){
			   that.searcharr2=userResp2.data.data.usrList;
		   }else{
			   that.searcharr2=[];
		   } 
		}else{
			that.searcharr2=[];
		}
		
	})).catch(function(err){})

# axios API

可以通过向 axios 传递相关配置来创建请求

axios(config) // 发送 POST 请求

axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
axios(url[, config])
// 发送 GET 请求(默认的方法)
axios('/user/12345');

# 请求方法的别名

为方便起见,为所有支持的请求方法提供了别名

  1. axios.request(config)
  2. axios.get(url[, config])
  3. axios.delete(url[, config])
  4. axios.post(url[, data[, config]])

......

  • 注意:在使用别名方法时, url、method、data 这些属性都不必在配置中指定。

# 创建实例

可以使用自定义配置新建一个 axios 实例

axios.create([config])

var instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

# 配置的默认值/defaults

你可以指定将被用在各个请求的配置默认值

# 全局的 axios 默认值

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

# 自定义实例默认值

 // 创建实例时设置配置的默认值
var instance = axios.create({
  baseURL: 'https://api.example.com'
});

// 在实例已创建后修改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

# 配置的优先顺序

配置会以一个优先顺序进行合并。这个顺序是:在 lib/defaults.js 找到的库的默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后者将优先于前者。这里是一个例子:

 // 使用由库提供的配置的默认值来创建实例
// 此时超时配置的默认值是 `0`
var instance = axios.create();

// 覆写库的超时默认值
// 现在,在超时前,所有请求都会等待 2.5 秒
instance.defaults.timeout = 2500;

// 为已知需要花费很长时间的请求覆写超时设置
instance.get('/longRequest', {
  timeout: 5000
});

# 拦截器

在请求或响应被 then 或 catch 处理前拦截它们。

 // 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });
 //如果你想在稍后移除拦截器,可以这样:
var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

可以为自定义 axios 实例添加拦截器

var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

# 错误处理

axios.get('/user/12345')
  .catch(function (error) {
    if (error.response) {
      // 请求已发出,但服务器响应的状态码不在 2xx 范围内
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });
//可以使用 validateStatus 配置选项定义一个自定义 HTTP 状态码的错误范围。

axios.get('/user/12345', {
  validateStatus: function (status) {
    return status < 500; // 状态码在大于或等于500时才会 reject
  }
})

# axios取消

使用 cancel token 取消请求

Axios 的 cancel token API 基于cancelable promises proposal,它还处于第一阶段。

可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<button id="kaishi">开始</button>
		<button id="zanting">暂停</button>
	</body>
	 <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	 <script type="text/javascript">
		 let kaishi=document.getElementById("kaishi")
		 let zangting=document.getElementById("zanting")
		 //方案1:通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token
		  const CancelToken = axios.CancelToken;
		  let cancel;
		  kaishi.onclick=function(){
			  axios.get("http://localhost:9000/ceshi",{
			 	  cancelToken: new CancelToken(function executor(c) {
			 		// executor 函数接收一个 cancel 函数作为参数
			 		cancel = c;
			 	  })
			 	}).then(data=>{
			  	console.log(data)
			  })
		  }
		  zanting.onclick=function(){
			  cancel();
		  }
		 
		 //方案2:使用cancelToken.sourse工厂方法创建cancel token
		 const CancelToken = axios.CancelToken;
		 const source = CancelToken.source();
		 kaishi.onclick=function(){
		 			 axios.get("http://localhost:9000/ceshi",{
							cancelToken: source.token
		 				}).then(data=>{
		 			 	console.log(data)
		 			 }).catch(e=>{
						 console.log(e)
						 console.log(e.message)//Operation canceled by the user.
					 })
		 }
		 zanting.onclick=function(){
		 			 source.cancel('Operation canceled by the user.');
		 }
		 
		 
	 
	 </script>
</html>

可以使用同一个 cancel token 取消多个请求,如果请求已经处于传输中,那么取消请求可能会导致请求超时或发生错误。如果服务器已经开始处理请求,那么取消请求可能不会产生任何效果。另外,有些请求可能无法被取消,例如那些没有配置为可取消的请求或者已经完成的请求。

# AbortController

AbortController 接口表示一个控制器对象,允许根据需要中止一个或多个 Web 请求。

可以使用 AbortController() 构造函数创建一个新的 AbortController 对象。使用 AbortSignal 对象可以完成与异步操作的通信。

最后更新: 4/7/2025, 1:34:14 PM