PRE
这是我参与更文挑战的第5天,活动详情查看: 更文挑战
本篇属于源码分析专栏
Axios 是什么?
Promise based HTTP client for the browser and node.js
从实现上来看,利用Promise + XMLHttpRequest简化请求流程
并且添加了许多方便的功能
如拦截器、统一header…
本文参考使用 TypeScript重构Axios
的流程进行展示,并添加一些自己的体会
前置知识
- 对URL的理解
- 理解XMLHttpRequest的使用和流程
- 理解Promise
这里大概提一下
利用浏览器提供的 new URL可以很方便的解析url
XMLHttpRequest
这个的关注点在于状态和相应状态的处理
利用eventTagrget提供的事件接口,可以更加方便和规范的处理不同的情况
developer.mozilla.org/en-US/docs/…
onreadystatechange
readyState === 4
⇓
onload / onerror / onabort
⇓
onloadend
复制代码
? 现在来开始着手实现Axios
处理AxiosRequestConfig 中的 params
有以下几种情况
- 常规
{
url: '/base/get',
params: {
a: 1,
b: 2
}
}
// url: /base/get?a=1&b=2
复制代码
- 数组
{
url: '/base/get',
params: {
foo: ['bar','foo']
}
}
// url: /base/get?foo[]=bar&foo[]=foo
复制代码
- 对象
{
url: '/base/get',
params: {
foo: {
bar: 'baz'
}
}
}
// url: /base/get?foo={"bar":"baz"}
// | encode
// url: /base/get?foo=%7B%22bar%22:%22baz%22%7D
复制代码
- Date
const date = new Date()
{
url: '/base/get',
params: {
date
}
}
const dataString = date.toISOString()
// url: /base/get?date=dataString
复制代码
- 特殊字符支持
对于字符 @
、:
、$
、,
、[
、]
、空格
我们是允许出现在 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,在对里面超出我们替换要求的符号进行重制
约定 空格
-> +
- 忽略undefined && null
- 丢弃hash
- 保留已有参数
处理body数据
注意使用isPlainObject
这里为什么要使用
isPlainObject
函数判断,而不用之前的isObject
函数呢,因为isObject
的判断方式,对于FormData
、ArrayBuffer
这些类型,isObject
判断也为true
,但是这些类型的数据我们是不需要做处理的,而isPlainObject
的判断方式,只有我们定义的普通JSON
对象才能满足。
XMLHttpRequest.send(body)
body
OptionalA body of data to be sent in the XHR request. This can be:
- A
Document
, in which case it is serialized before being sent.- An
XMLHttpRequestBodyInit
, which per the Fetch spec can be aBlob
,BufferSource
,FormData
,URLSearchParams
, orUSVString
object.null
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
源码的真的是最好的老师 || 文档~