? 源码分析:Axios

PRE

这是我参与更文挑战的第5天,活动详情查看: 更文挑战

本篇属于源码分析专栏

Axios 是什么?

Promise based HTTP client for the browser and node.js

从实现上来看,利用Promise + XMLHttpRequest简化请求流程

并且添加了许多方便的功能

如拦截器、统一header…

本文参考使用 TypeScript重构Axios

younglele.cn/ts-axios-do…

的流程进行展示,并添加一些自己的体会

前置知识

  • 对URL的理解
  • 理解XMLHttpRequest的使用和流程
  • 理解Promise

这里大概提一下

利用浏览器提供的 new URL可以很方便的解析url

blog.bitsrc.io/using-the-u…

image-20210605160721083

XMLHttpRequest

这个的关注点在于状态和相应状态的处理

利用eventTagrget提供的事件接口,可以更加方便和规范的处理不同的情况
developer.mozilla.org/en-US/docs/…

javascript.info/xmlhttprequ…

    	 onreadystatechange
      	readyState === 4
             ⇓
     onload / onerror / onabort
                 ⇓
            onloadend


复制代码

? 现在来开始着手实现Axios

处理AxiosRequestConfig 中的 params

有以下几种情况

  1. 常规
{
  url: '/base/get',
    params: {
      a: 1,
      b: 2
    }
}
// url: /base/get?a=1&b=2
复制代码
  1. 数组
{
  url: '/base/get',
  params: {
    foo: ['bar','foo']
  }
}
// url: /base/get?foo[]=bar&foo[]=foo
复制代码
  1. 对象
{
  url: '/base/get',
  params: {
    foo: {
      bar: 'baz'
    }
  }
}
// url: /base/get?foo={"bar":"baz"} 
// | encode
// url: /base/get?foo=%7B%22bar%22:%22baz%22%7D
复制代码
  1. Date
const date = new Date()
{
  url: '/base/get',
  params: {
    date
  }
}
const dataString = date.toISOString()
// url: /base/get?date=dataString
复制代码
  1. 特殊字符支持

对于字符 @:$,[]空格 我们是允许出现在 url 中的,不希望被 encode。

两个相关的原生API

encodeURIComponent() escapes all characters except:

Not Escaped:

    A-Z a-z 0-9 - _ . ! ~ * ' ( )
复制代码

encodeURI() escapes all characters except:

Not Escaped:

    A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #
复制代码

这里使用encodeURIComponent进行encode,在对里面超出我们替换要求的符号进行重制

约定 空格 -> +

  1. 忽略undefined && null
  2. 丢弃hash
  3. 保留已有参数

URI syntax diagram

处理body数据

注意使用isPlainObject

这里为什么要使用 isPlainObject 函数判断,而不用之前的 isObject 函数呢,因为 isObject 的判断方式,对于 FormDataArrayBuffer 这些类型,isObject 判断也为 true,但是这些类型的数据我们是不需要做处理的,而 isPlainObject 的判断方式,只有我们定义的普通 JSON 对象才能满足。

XMLHttpRequest.send(body)

body Optional

A body of data to be sent in the XHR request. This can be:

If no value is specified for the body, a default value of null is used.

axios({
  method: 'post',
  url: '/base/post',
  data: { 
    a: 1,
    b: 2 
  }
})
复制代码

这样的需求是要转换为string的

Unicode Scalar Value. Any Unicode code point except high-surrogate and low-surrogate code points. In other words, the ranges of integers 0 to D7FF16 and E00016 to 10FFFF16 inclusive. (See definition D76 in Section 3.9, Unicode Encoding Forms.)

关于 DOMString vs USVString

这里有个 issue github.com/w3ctag/desi…

个人对这里的理解是

USVString URL环境

DOMString 除了URL的环境 (JS,文本处理?

END

内容较长、分为若干篇~

欢迎关注 SedationH

源码的真的是最好的老师 || 文档~

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享