一比一还原axios源码(八)—— 其他功能

到此,我们完成了axios的绝大部分的功能,接下来我们来补全一下其他的小功能。一、withCredentials这个参数可以可以表明是否是一个跨域的请求。那这个的使用场景是啥呢?就是我们在同域的请

大家好,又见面了,我是你们的朋友全栈君。

  到此,我们完成了axios的绝大部分的功能,接下来我们来补全一下其他的小功能。

一、withCredentials

<span role="heading" aria-level="2">一比一还原axios源码(八)—— 其他功能

   这个参数可以可以表明是否是一个跨域的请求。那这个的使用场景是啥呢?就是我们在同域的请求的情况下,是会默认携带cookie的,跨域的话就不会携带cookie,如果我们想要跨域请求并携带cookie,那么就需要这个参数了。当然这个实现非常简单:

    if (!utils.isUndefined(config.withCredentials)) {
      request.withCredentials = !!config.withCredentials;
    }

  嗯,就这样就完了。

  然后我们需要创建一个作为接受跨域请求的server2.js作为跨域访问的服务器。代码可以在gitHub上看哦。就不多说了。

二、XSRF 防御

  就是跨站请求伪造,登录信任的A网站后会产生该用户的信任cookie,由于浏览器在发送请求的时候会自动携带cookie,如果用户在没有登出的情况下登录黑客网站,那么就会把带有信任的cookie传递给黑客网站,此时黑客网站拿到你的用户cookie就可以伪造用户登录A网站了。

  XSRF的防御手段有很多,比如referer,但是referer也是可以伪造的,所以杜绝此类攻击的一种方式是服务器端要求每次请求都包含一个token,这个token不在前端生成,而是在我们每次访问站点的时候生成,并通过set-cookie的方式种到客户端,然后客户端发送请求的时候,从cookie中对应的字段读取出token,然后添加到请求headers中。这样服务端就可以从请求headers中读取这个token并验证,由于这个token 是很难伪造的,所以就能区分这个请求是否是用户正常发起的。

  所以在axios中,我们需要自动把这些事情做了,每次发送请求的时候,从cookie中读取对应的token值,然后添加到请求headers中。我们允许用户配置xsrfCookieNamexsrfHeaderName,其中xsrfCookieName表示存储tokencookie名称,xsrfHeaderName表示请求headerstoken对应的header名称。

   例子就像这样:

const instance = axios.create({
  xsrfCookieName: 'XSRF-TOKEN-D',
  xsrfHeaderName: 'X-XSRF-TOKEN-D'
})

instance.get('/more/get').then(res => {
  console.log(res)
})

  那么接下来我们来看下代码的实现:

  首先,我们在defaults中添加两个默认参数:

var defaults = {
// ...
  xsrfCookieName: "XSRF-TOKEN",
  xsrfHeaderName: "X-XSRF-TOKEN",
// ...

}

  首先啊,我们要做一些判断,首先要判断如果是配置 withCredentials 为 true 或者是同域请求,我们才会请求 headers 添加 xsrf 相关的字段,然后我们在helpers文件夹下创建一个isURLSameOrigin文件,用来判断是否是同源,我直接从axios复制过来的,哈哈。代码大家自己去看注释哦。它的核心其实就是创建个a标签,然后设置属性为我们传入的url地址,通过这个DOM,我们就可以获取到对应url的protocol、host等属性,然后我们判断这两个是否相同就可以了。

  然后,我们在创建个cookies文件,也是在helpers文件夹中,这个cookies主要封装了一些cookie的读写操作。

  最后,就是我们的核心逻辑代码了,其实很简单:

    if (utils.isStandardBrowserEnv()) {
      // Add xsrf header
      var xsrfValue =
        (config.withCredentials || isURLSameOrigin(config.url)) &&
        config.xsrfCookieName
          ? cookies.read(config.xsrfCookieName)
          : undefined;
      if (xsrfValue) {
        requestHeaders[config.xsrfHeaderName] = xsrfValue;
      }
    }

  首先判断是否是浏览器环境,如果是的话,就再判断是否有withCredentials或者是同源的,并且有xsrfCookieName,然后读取cookie中的xsrfCookieName的值,然后设置给headers即可。其实核心逻辑并不复杂,复杂的是XSRF的概念,和一些它的判断条件中的方法。

  最后,在我们的demo里,我们还要设置下server.js:

app.use(express.static(__dirname, {
  setHeaders (res) {
    res.cookie('XSRF-TOKEN-D', '1234abc')
  }
}))

  这样才可以。

三、上传下载进度监控

  其实上传和下载的进度监控,都可以通过xhr的原生的对象来进行获取。这是axios的文档:

<span role="heading" aria-level="2">一比一还原axios源码(八)—— 其他功能

   我们先来看实现吧,实现起来非常简单,其实就是传了个参数,xhr里调用一下:

    // Handle progress if needed
    if (typeof config.onDownloadProgress === 'function') {
      request.addEventListener('progress', config.onDownloadProgress);
    }

    // Not all browsers support upload events
    if (typeof config.onUploadProgress === 'function' && request.upload) {
      request.upload.addEventListener('progress', config.onUploadProgress);
    }

  就这么简单,完事了。。。。demo的话我就不在这里占篇幅了,大家去项目里看下。

四、Authorization

  HTTP 协议中的 Authorization 请求 header 会包含服务器用于验证用户代理身份的凭证,通常会在服务器返回 401 Unauthorized 状态码以及 WWW-Authenticate 消息头之后在后续请求中发送此消息头。

  axios 库也允许你在请求配置中配置 auth 属性,auth 是一个对象结构,包含 username 和 password 2 个属性。一旦用户在请求的时候配置这俩属性,我们就会自动往 HTTP 的 请求 header 中添加 Authorization 属性,它的值为 Basic 加密串。 这里的加密串是 username:password base64 加密后的结果。

  axios文档中是这样说明的:

<span role="heading" aria-level="2">一比一还原axios源码(八)—— 其他功能 

   我们来看下代码实现:

// HTTP basic authentication
if (config.auth) {
  var username = config.auth.username || "";
  var password = config.auth.password
    ? unescape(encodeURIComponent(config.auth.password))
    : "";
  requestHeaders.Authorization = "Basic " + btoa(username + ":" + password);
}

  就这么简单~~。

五、自定义合法状态码

  首先,我们还是来看官方的文档:
<span role="heading" aria-level="2">一比一还原axios源码(八)—— 其他功能
  也就是说,我们可以通过validateStatus参数,自定义哪些状态码是合法的。那,我们需要给defaults对象一个默认的validateStatus:
<span role="heading" aria-level="2">一比一还原axios源码(八)—— 其他功能

  额。。。跟文档一模一样。。。。那我们在判断promise是走resolve还是reject的时候,就要额外的处理下了,对了,大家还记得我们实在哪里执行的了不?还记不记得有个settle文件?

export default function settle(resolve, reject, response) {
  var validateStatus = response.config.validateStatus;
  if (!response.status || !validateStatus || validateStatus(response.status)) {
    resolve(response);
  } else {
    reject(
      createError(
        "Request failed with status code " + response.status,
        response.config,
        null,
        response.request,
        response
      )
    );
  }
}

  嗨(四声)!就是个判断!

六、自定义参数序列化

  我们先来看文档:

<span role="heading" aria-level="2">一比一还原axios源码(八)—— 其他功能

 

   这个东西呢,允许我们自己定义规则解析url后的query参数,大多数情况下用不到吼。

七、baseURL

  有些时候,我们会请求某个域名下的多个接口,我们不希望每次发送请求都填写完整的 url,希望可以配置一个 baseURL,之后都可以传相对路径。我们一旦配置了 baseURL,之后请求传入的 url 都会和我们的 baseURL 拼接成完整的绝对地址,除非请求传入的 url 已经是绝对地址。

<span role="heading" aria-level="2">一比一还原axios源码(八)—— 其他功能          

   我们需要两个辅助函数:
combineURLs和isAbsoluteURL,然后再通过这两个辅助函数,构建一个buildFullPath核心方法。然后在xhr中直接调用buildFullPath即可:
var fullPath = buildFullPath(config.baseURL, config.url);
request.open(
  config.method.toUpperCase(),
  buildURL(fullPath, config.params, config.paramsSerializer),
  true
);

八、静态方法扩展

  额。。。直接看代码吧,懒得说了~~~

  首先,扩展几个静态方法:

// Expose all/spread
axios.all = function all(promises) {
  return Promise.all(promises);
};
axios.spread = function spread(callback) {
  return function wrap(arr) {
    return callback.apply(null, arr);
  };
};

// Expose isAxiosError
axios.isAxiosError = function isAxiosError(payload) {
  return utils.isObject(payload) && payload.isAxiosError === true;
};

  然后,扩展个getUri方法:

Axios.prototype.getUri = function getUri(config) {
  config = mergeConfig(this.defaults, config);
  return buildURL(config.url, config.params, config.paramsSerializer).replace(
    /^\?/,
    ""
  );
};

  撒花,完结~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/124365.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Modelsim下载 安装 与 和谐教程

    Modelsim下载 安装 与 和谐教程一.下载ModelsimSE-642019.2-windows网盘分享:链接:https://pan.baidu.com/s/1BASOJ1DYZYrK9Ot_BRs7HA提取码:md4d二.安装下载完压缩包后解压,安装按下图所示步骤进行。注意,完全退出杀毒软件如360,否则可能安装/和谐失败。自此安装完成,下面进行和谐。三.和谐运行patch.dll会生成LICENSE.TXT文件,将此文件另存到modelsim安装路径下。建立用户环境变量:.

  • APK签名机制原理详解

    APK签名机制原理详解众所周知,Android系统在安装Apk的过程中,会对Apk进行签名校验,校验通过后才能安装成功。那你知道签名校验的机制是什么?具体校验的是什么内容吗?申请第三方SDK(如微信支付)时填入的SAH1值是什么?目前众多的快速批量打包方案又是如何绕过签名检验的?我将通过一系列的文章来解开这些疑惑。

  • mac全选文字的快捷键_关于mac文本的快捷键你知道多少?[通俗易懂]

    mac全选文字的快捷键_关于mac文本的快捷键你知道多少?[通俗易懂]用惯了windows系统的小伙伴,对于苹果的快捷键一定很不习惯。所以贴心的小编为大家准备了关于mac打字的快捷键你知道多少?用习惯了苹果的快捷键也是非常好用的哦!在电脑的操作过程中,快捷键是非常主要的,为您节省了很多不必要的时间,提高了工作的效率,下面就和小编一起来看一看有哪些好用的快捷键吧!关于mac的快捷键你知道多少?:cmd+c。复制cmd+v。粘贴cmd+a。全选cmd+tab。切换程序s…

  • Postman下载安装

    Postman下载安装一、Postman下载1、Postman64位安装包下载:链接:https://pan.baidu.com/s/1lInTrSfW9PMmYI6OsUS2tg提取码:nvbw2、Postman32位安装包下载:链接:https://pan.baidu.com/s/1S_7K9wqyDwuoe-mjQowpKQ提取码:sw7g3、官网下载:地址:https://www.getpostman.com/downloads/,选择页面中的“Download”,根据自己电脑配置,选择32位下载还是64

  • Linux#使用ll命令

    Linux#使用ll命令     ubuntu和mac环境下,没有ll命令,对于习惯在Linux环境使用ll命令的开发人员来说,着实不便。     介绍两种添加ll命令的方法:     一、设置别名        1、编辑~/.bashrc mac环境为~./bash_profile             sudovim~/.bash_profile        2、…

  • BN层的作用_bn层加在哪里

    BN层的作用_bn层加在哪里一:BN层李宏毅视频讲解BN(BatchNormalization)层的作用(1)加速收敛(2)控制过拟合,可以少用或不用Dropout和正则(3)降低网络对初始化权重不敏感(4)允许使用较大的学习率 链接:https://www.zhihu.com/question/38102762/answer/85238569来源:知乎1.WhatisBN?顾名思义,batchnormalizat…

    2022年10月10日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号