# axios
HTTP 相关
MDN 文档
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview
HTTP 请求基本过程

- 01 浏览器端向服务器发送 HTTP 请求(请求报文)
- 02 后台服务器接收到请求后,处理请求,向浏览器端返回 HTTP 响应(响应报文)
- 03 浏览器端接收到响应,解析显示响应体或调用回调函数
HTTP 请求报文
请求行
- 格式 : method url
- 例如 : GET /product_detail?id=2 或 POST /login
请求头
- Host: www.baidu.come
- Cookie: BAIDUID=AD3B0FA706E; BIDUPSID=AD3BOFA706;
- Content-Type: application/x-www-form-urlencoded 或者 application/json
请求体
- username=tom&pwd=123
- {“username”: “tom”, “pwd”: 123}
- get 请求没有请求体
HTTP 响应报文
响应行
- 格式: status statusText
- 例如: 200 OK 或 404 Not Found
响应头
- Cortent-Type: text/html;charset=utf-8
- Set-Cookie: BD_CK_SAM=1;path=/
响应体
常见的响应状态码
- 200 OK 请求成功。一般用于 GET 与 POST 请求
- 201 Created 已创建。成功请求并创建了新的资源
- 401 Unauthorized 未授权 / 请求要求用户的身份认证
- 404 Not Found 服务器无法根据客户端的请求找到资源
- 500 Internal Server Error 服务器内部错误,无法完成请求
请求方式
01 GET (索取) : 从服匀器端读取数据—–查(R)
02 POST (交差) : 向服务器端添加新数据——增(C)
03 PUT : 更新服务器端已存在的数据——-改(U)
04 DELETE : 删除服务器端数据———删(D)
请求参数
query 参数
- 01 参数包含在请求地址中,格式为: /xxxx?name=tom&age=18
- 02 敏感数据不要用 query 参数,因为参数是地址的一部分,比较危险,比如用户密码。
- 03 备注: query 参数又称查询字符串参数,编码方式为 urlencoded
params 参数
请求体参数
注意点
- 01 GET 请求不能携带请求体参数,因为 GET 请求没有请求体。
- 02 理论上一次请求可以随意使用上述 3 种类型参数中的任何一种,甚至一次请求的 3 个参数可以用 3 种形式携带,但一般不这样做。
- 03 一般来说我们有一些“约定俗成”的规矩:
- (1) 例如 form 表单发送 post 请求时:自动使用请求体参数,用 urlencoded 编码。
- (2) 例如 jQuery 发送 ajax-post 请求时:自动使用请求体参数,用 urlencoded 编码。
- 04 开发中请求到底发给谁?用什么请求方式?携带什么参数?—-要参考项目的 API 接口
API 相关
API 分类
- 01 REST API
- restful 风格的 API
- 发送请求进行 CRUD , 哪个操作由请求方式来决定
- 同一个请求路径可以进行多个操作
- 请求方式会用到 GET / POST / PUT / DELETE
- 02 非 REST API
- restless 风格的 API
- 请求方式不决定请求的 CRUD 操作
- 一个请求路径只对应—个操作
- 一般只有 GET / POST
json-server 的使用
1
| npm install -g json-server
|
1
| json-server --watch db.json
|
postman 测试接口
一般 http 请求与 ajax 请求
- 01 ajax 请求是一种特别的 http 请求
- 02 对服务器端来说,没有任何区别,区别在浏览器端
- 03 浏览器端发请求: 只有 XHR 或 fetch 发出的才是 ajax 请求,其它所有的都是非 ajax 请求
- 04 浏览器端接收到响应
- (1) 一般请求:浏览器一般会直接显示响应体数据,也就是我们常说的自动刷新 / 跳转页面
- (2) ajax 请求:浏览器不会对界面进行任何更新操作,只是调用监视的回调函数并传入响应相关数据
03 axios
axios 是什么
axios 特点
- 01 基本 promise 的异步 ajax 请求库
- 02 浏览器端 / node 端都可以使用
- 03 支持请求 / 响应拦截器
- 04 支持请求取消
- 05 请求 / 响应数据转换
- 06 批量发送多个请求
使用 axios 发起 ajax 请求
01 axios 调用的返回值是 Promise 实例对象。
02 成功的值叫 response,失败的值叫 error
03 axios 成功的值是一个 axios 封装的 response 对象,服务器返回的真正数据在 response.data 中
完整写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.0.0-alpha.1/axios.min.js"></script>
<body> <button id="btn1">按钮</button> <script> const btn1 = document.getElementById('btn1') btn1.onclick = () => { axios({ url: 'http://localhost:5000/persons', method: 'GET', }).then( (response) => { console.log('请求成功了', response.data) }, (error) => { console.log('请求失败了', error) } ) } </script> </body>
|
1 2 3 4 5 6 7 8 9 10 11
| btn1.onclick = () => { axios.get('http://localhost:5000/persons').then( (response) => { console.log('请求成功了', response.data) }, (error) => { console.log('请求失败了', error) } ) }
|
1 2 3 4 5
| btn1.onclick = async () => { const result = await axios.get('http://localhost:5000/persons') console.log(result.data) }
|
携带 query 参数发 get 请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| btn2.onclick = () => { axios({ url: 'http://localhost:5000/person', method: 'GET', params: { id: personId.value }, }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
1 2 3 4 5 6 7 8 9 10 11 12
| btn2.onclick = () => { axios.get('http://localhost:5000/person', { params: { id: personId.value } }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
携带请求体参数发起 post 请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| btn3.onclick = () => { axios({ url: 'http://localhost:5000/person', method: 'POST', data: `name=${personName.value}&age=${personAge.value}`, }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
1 2 3 4 5 6 7 8 9 10 11 12
| btn3.onclick = () => { axios.get('http://localhost:5000/person', { name: personName.value, age: personAge.value }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
携带请求体参数发起 PUT 请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| btn4.onclick = () => { axios({ url: 'http://localhost:5000/person', method: 'PUT', data: { id: personUpdateID.value, name: personUpdateName.value, age: personUpdateAge.value, }, }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| btn4.onclick = () => { axios .put('http://localhost:5000/person', { id: personUpdateID.value, name: personUpdateName.value, age: personUpdateAge.value, }) .then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
携带 params 参数发起 delete 请求
1 2 3 4 5 6 7 8 9 10 11 12 13
| btn5.click = () => { axios({ url: `http://localhost:5000/person/${personDeleteId.value}`, method: 'DELETE', }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
axios 的常用配置项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| axios.defaults.timeout = 2000 axios.defaults.headers = { token: 'a15g1eg51d854ge5151eged' } axios.defaults.baseURL = 'http://localhost:5000'
btn6.click = () => { axios({ url: `/person`, method: 'get', }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
axios 的 create 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const axios2 = axios.create({ timeout: 2000, headers: { token: 'a15g1eg51d854ge5151eged' }, baseURL: 'http://localhost:5000', })
btn7.click = () => { axios2({ url: `/person`, method: 'GET', }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
请求拦截器
- 01 请求拦截器是什么?
- 02 请求拦截器的作用:
- 对所有的请求做统一的处理: 比如 追加请求头、追加参数、界面 loading 提示等等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| axios.interceptors.request.use((config) => { config.headers.token = 'a2g6e1g51dge48g51' return config })
btn8.click = () => { axios({ url: `http://localhost:5000/person`, method: 'GET', }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
响应拦截器
- 01 响应拦截器是什么?
- 02 响应拦截器作用:
- 若请求成功,对成功的数据进行处理, 若请求失败,对失败进行统一的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| axios.interceptors.response.use( (res) => { console.log('响应拦截器成功的回调', res) return res.data }, (err) => { console.log('响应拦截器失败的回调', err) return Promise.reject(err) } )
btn9.click = () => { axios({ url: `http://localhost:5000/person`, method: 'GET', }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| axios.interceptors.response.use( (res) => { console.log('响应拦截器成功的回调', res) return res.data }, (err) => { console.log('响应拦截器失败的回调', err) return new Promise(() => {}) } )
btn9.click = async () => { const result = await axios.get('http://localhost:5000/persons') console.log(result) }
|
取消请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const { CancelToken } = axios let cancel
btn10.click = () => { axios({ url: `http://localhost:5000/person`, cancelToken: new CancelToken((c) => { cancel = c }), }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) } ) }
btn11.onclick = () => { cancel('我是取消请求的提示信息,任性取消,就是不要数据了~~') }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| const { CancelToken, isCancel } = axios let cancel
btn10.click = () => { if (cancel) { cancel() } axios({ url: `http://localhost:5000/person`, cancelToken: new CancelToken((c) => { cancel = c }), }).then( (res) => { console.log('请求成功了', res.data) }, (err) => { if (isCancel(error)) { console.log('用户取消了请求,原因是:', error.message) } else { console.log('请求失败了', err) } } ) }
btn11.onclick = () => { cancel('我是取消请求的提示信息,任性取消,就是不要数据了~~') }
|
请求拦截器中取消请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| const { CancelToken, isCancel } = axios let cancel
axios.interceptors.request.use((config) => { if (cancel) { cancel('取消了') } config.cancelToken = new CancelToken((c) => { cancel = c }) return config })
axios.interceptors.response.use( (res) => { console.log('响应拦截器成功的回调', res) return res.data }, (err) => { if (isCancel(error)) { console.log('用户取消了请求,原因是:', error.message) } else { console.log('请求失败了', err) } return new Promise(() => {}) } )
btn10.click = async () => { const result = await axios.get('http://localhost:5000/persons') console.log(result) }
|
批量发起请求
1 2 3 4 5 6 7 8 9 10 11 12 13
| btn.onclick = () => { axios.all([axios.get('http://localhost:5000/persons1'), axios.get('http://localhost:5000/persons2'), axios.get('http://localhost:5000/persons3')]).then( (res) => { console.log(res) }, (err) => { console.log(err) } ) }
|
扩展
生成 api 文档的工具