Skip to content

本节主要总结 Axios 提供的一些特殊功能点。

9-1.上传、下载进度

现代浏览器端通信有 XMLHttpRequestfetch 两种方式。

关于这俩者较为详细的介绍,可以参考XHR/FETCH

截止到目前,XMLHttpRequest 提供了 xhr.uploadxhr.onprogress 来监听上传和下载进度。

fetch 这方面则欠缺一些,并没有提供原生的上传和下载监听 API

我们已经知道 Axiosbrowser 端使用的就是 XMLHttpRequest

可想而知,Axios 对于上传和下载进度的监听,内部实现依赖的是 XMLHttpRequest

本章节,重点说明下 Axios 相应 API 的使用方式。

config 中,Axios 提供了两个属性 onUploadProgressonDownloadProgress

js
const config = {
  onUploadProgress: function (event) {
    console.log(event)
  },
  onDownloadProgress: function (event) {
    console.log(event)
  }
}

9-2.取消请求

XMLHttpRequest 中提供了 xhr.abort() 来直接中止请求。

fetch 则是使用 AbortController 来中止请求。

那么 Axios 最开始是手动封装了 CancelToken 方法,内部主要实现依旧是将 xhr.abort() 进行 Promise 化包装。

当出现了原生方法 AbortController 之后,Axios 为了面向未来,内部兼容了 AbortController,而且更加推荐使用 AbortController

CancelToken 在较高版本中的 Axios 已经逐渐被废弃。

9-2-1.CancelToken

笔者认为,CancelToken 是基于 xhr.abort() 方法封装的中止 Promise 方法的 API

还有一个关于 CancelToken 的设计提案cancelable promises proposal

Axios 中的基本使用方式如下:

js
const { CancelToken } = axios
const source = CancelToken.source()

axios({
  url: '/api',
  params: {
    id: '9527'
  },
  cancelToken: source.token
}).then(res => {
  console.log(res)
}).catch(err => {
  console.error(err)
})

source.cancel()

打印 source 属性如下:

9-2-2.AbortController

关于 AbortController 的详细信息,可以参考 AbortController

本节主要总结下 AbortController 的使用方式和注意事项。

js
const abortController = new AbortController()
const { signal } = abortController

axios({
  url: '/api',
  params: {
    id: '9527'
  },
  signal
}).then(res => {
  console.log(res)
}).catch(err => {
  console.error(err)
})

abortController.abort()

abortController.signal 属性打印如下:

9-3.XSRF防范

关于 XSRF 的基本机制,是利用了访问某站时,该站对应的 cookie 会被浏览器自动携带。

而攻击者则可以利用伪造页面,诱导用户点击,请求携带用户本机已经种好的 cookie,进而触发不安全交易。

关于 XSRF 的更多详细内容,可以参考XSRF攻击及防范

而在 Axios 中,防范 XSRF 的手段,一般可以称作双重 Cookie 防御

具体交互逻辑如下:

  1. 服务端利用一些加密方式生成 Token,然后通过 Set-Cookie 返回给客户端,然后客户端在发起交易时,读取对应 Cookie,并设置到请求头 headers 中,假设我们将其命名为 Cookie Token
  2. 发起交易时,实际请求会发送本地 Cookie,还会发送在请求头中设置的 Cookie Token
  3. 也就是说,服务端在做交易验证时,不单单要验证请求头中的 Cookie 字段,还要验证 Cookie Token 字段。

Axios 中,config 属性中提供了两个字段:xsrfCookieNamexsrfHeaderName

下面代码是 Axios 对于 xsrfCookieNamexsrfHeaderName 的处理逻辑:

js
if (platform.isStandardBrowserEnv) {
  // Add xsrf header
  const xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath))
    && config.xsrfCookieName && cookies.read(config.xsrfCookieName);

  if (xsrfValue) {
    requestHeaders.set(config.xsrfHeaderName, xsrfValue);
  }
}

可以看出,Axios 是将本地与 xsrfCookieName 对应的 Cookie 取出,然后按照 xsrfHeaderName 设置到请求头上。

该实现与我们所分析的双重 Cookie 防御逻辑是一致的。