axios核心原理(笔记)
axios 从入门到源码分析
第1章:HTTP 相关
1.1. MDN 文档
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview
1.2 HTTP 请求交互的基本过程
- 前后应用从浏览器端向服务器发送 HTTP 请求(请求报文)
- 后台服务器接收到请求后,调度服务器应用处理请求,向浏览器返回 HTTP 响应(响应报文)
- 浏览器端接收到响应, 解析显示响应体/调用监视回调
1.3. HTTP 请求报文
- 请求行
method url
GET /product_detail?id=2
POST /login
- 多个请求头
Host: www.baidu.com
Cookie: BAIDUID=AD3B0FA706E; BIDUPSID=AD3B0FA706;
Content-Type: application/x-www-form-urlencoded 或者application/json
- 请求体
username=tom&pwd=123
{"username": "tom", "pwd": 123}
1.4. HTTP 响应报文
- 响应状态行:
status statusText
- 多个响应头
Content-Type: text/html;charset=utf-8
Set-Cookie: BD_CK_SAM=1;path=/
- 响应体
html 文本/json 文本/js/css/图片...
1.5. post 请求体参数格式
Content-Type: application/x-www-form-urlencoded;charset=utf-8
用于键值对参数,参数的键值用=
连接, 参数之间用&
连接 例如:name=%E5%B0%8F%E6%98%8E&age=12
Content-Type: application/json;charset=utf-8
用于json
字符串参数 例如:{"name": "%E5%B0%8F%E6%98%8E", "age": 12}
Content-Type: multipart/form-data
用于文件上传请求
1.6. 常见的响应状态码
200 OK 请求成功。一般用于 GET 与 POST 请求
201 Created 已创建。成功请求并创建了新的资源
401 Unauthorized 未授权/请求要求用户的身份认证
404 Not Found 服务器无法根据客户端的请求找到资源
500 Internal Server Error 服务器内部错误,无法完成请求
1.7. 不同类型的请求及其作用
GET
: 从服务器端读取数据POST
: 向服务器端添加新数据PUT
: 更新服务器端已经数据DELETE
: 删除服务器端数据
1.8. API 的分类
REST API
:restful
(1) 发送请求进行CRUD
哪个操作由请求方式来决定
(2) 同一个请求路径可以进行多个操作
(3) 请求方式会用到GET/POST/PUT/DELETE
- 非
REST API
:restless
(1) 请求方式不决定请求的CRUD
操作
(2) 一个请求路径只对应一个操作
(3) 一般只有GET/POST
1.9. 使用 json-server 搭建 REST API
1.9.1. json-server 是什么?
- 用来快速搭建 REST API 的工具包
1.9.2. 使用 json-server
- 在线文档: https://github.com/typicode/json-server
- 下载:
npm install -g json-server
- 目标根目录下创建数据库
json
文件:db.json
{
"posts":
[
{
"id": 1, "title": "json-server", "author": "typicode" }
],
"comments":
[
{
"id": 1, "body": "some comment", "postId": 1 }
],
"profile": {
"name": "typicode" }
}
- 启动服务器执行命令:
json-server --watch db.json
1.9.3. 使用浏览器访问测试
- http://localhost:3000/posts
- http://localhost:3000/posts/1
1.9.4. 使用 axios 访问测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div>
<button onclick="testGet()">GET请求</button>
<button onclick="testPost()">POST请求</button>
<button onclick="testPut()">PUT请求</button>
<button onclick="testDelete()">DELETE请求</button>
</div>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
<script>
function testGet() {
// axios.get('http://localhost:3000/posts')
// axios.get('http://localhost:3000/posts/1')
axios.get('http://localhost:3000/posts?id=1')
.then(response => {
console.log('/posts get', response.data)
})
}
function testPost() {
axios.post('http://localhost:3000/posts', {
"title": "json-server3", "author": "typicode3" })
.then(response => {
console.log('/posts post', response.data)
})
}
function testPut() {
axios.put('http://localhost:3000/posts/3', {
"title": "json-server...", "author": "typicode..." })
.then(response => {
console.log('/posts put', response.data)
})
}
function testDelete() {
axios.delete('http://localhost:3000/posts/3')
.then(response => {
console.log('/posts delete', response.data)
})
}
</script>
</body>
</html>
第2章:XHR 的理解和使用
2.1. MDN 文档
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
2.2. 理解
- 使用
XMLHttpRequest (XHR)
对象可以与服务器交互, 也就是发送ajax
请求 - 前端可以获取到数据,而无需让整个的页面刷新。
- 这使得
Web
页面可以只更新页面的局部,而不影响用户的操作。
2.3. 区别一般 http 请求与 ajax 请求
ajax
请求是一种特别的http
请求- 对服务器端来说, 没有任何区别, 区别在浏览器端
- 浏览器端发请求: 只有
XHR
或fetch
发出的才是ajax
请求, 其它所有的都是非ajax
请求 - 浏览器端接收到响应
(1) 一般请求: 浏览器一般会直接显示响应体数据, 也就是我们常说的刷新/ 跳转页面
(2)ajax
请求: 浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应相关数据
2.4. API
XMLHttpRequest()
: 创建XHR
对象的构造函数status
: 响应状态码值, 比如200, 404
statusText
: 响应状态文本readyState
: 标识请求状态的只读属性
0
: 初始1
:open()
之后2
:send()
之后3
: 请求中4
: 请求完成
onreadystatechange
: 绑定readyState
改变的监听responseType
: 指定响应数据类型, 如果是json
, 得到响应后自动解析响应体数据response
: 响应体数据, 类型取决于responseType
的指定timeout
: 指定请求超时时间, 默认为0
代表没有限制ontimeout
: 绑定超时的监听onerror
: 绑定请求网络错误的监听open()
: 初始化一个请求, 参数为:(method, url[, async])
send(data)
: 发送请求abort()
: 中断请求getResponseHeader(name)
: 获取指定名称的响应头值getAllResponseHeaders()
: 获取所有响应头组成的字符串setRequestHeader(name, value)
: 设置请求头
2.5. XHR
的 ajax
封装(简单版 axios
)
2.5.1. 特点
- 函数的返回值为
promise
, 成功的结果为response
, 异常的结果为error
- 能处理多种类型的请求:
GET/POST/PUT/DELETE
- 函数的参数为一个配置对象
{
url: '', // 请求地址
method: '', // 请求方式 GET/POST/PUT/DELETE
params: {
}, // GET/DELETE 请求的 query 参数
data: {
} // POST 或 PUT 请求的请求体参数
}
- 响应
json
数据自动解析为js
2.5.2. 编码实现
/*
1. 函数的返回值为 `promise`, 成功的结果为 `response`, 异常的结果为 `error`
2. 能处理多种类型的请求: `GET/POST/PUT/DELETE`
3. 函数的参数为一个配置对象
{
url: '', // 请求地址
method: '', // 请求方式 GET/POST/PUT/DELETE
params: {}, // GET/DELETE 请求的 query 参数
data: {} // POST 或 PUT 请求的请求体参数
}
4. 响应 `json` 数据自动解析为 `js`
*/
function axios({
url,
method = 'GET',
params = {
},
data = {
}
}) {
// 返回一个 Promise 对象
return new Promise((resolve, reject) => {
// 处理 method
method = method.toUpperCase()
// 处理 query 参数(拼接到 url 上)id=1&xxx=abc
/*
{
id: 1,
xxx: 'abc'
}
*/
let queryString = ''
Object.keys(params).forEach(key => {
queryString += `${
key}=${
params