Axios
2334 字
12 分钟
Axios
创建 API
API 的分类
- REST API: restful (Representational State Transfer (资源)表现层状态转化)
- 发送请求进行CRUD 哪个操作由请求方式来决定
- 同一个请求路径可以进行多个操作
- 请求方式会用到GET/POST/PUT/DELETE
- 非REST API: restless
- 请求方式不决定请求的CRUD 操作
- 一个请求路径只对应一个操作
- 一般只有GET/POST
使用json-server 搭建REST API
json-server
json-server 是用来快速搭建REST API 的工具包
使用json-server
- 在线文档: https://github.com/typicode/json-server
- 下载:
npm install -g json-server - 目标根目录下创建数据库 json 文件:
db.json
{ "posts": [ { "id": 1, "title": "json-server", "author": "typicode" }, { "id": 2, "title": "json-server2", "author": "typicode" } ], "comments": [ { "id": 1, "body": "some comment", "postId": 1 } ], "profile": { "name": "typicode" }}- 启动服务器执行命令:
json-server --watch db.json - 使用浏览器访问测试
http://localhost:3000/posts
XHR 的 ajax封装 (简单版axios)
特点
- 函数的返回值为
promise, 成功的结果为response, 失败的结果为error - 能处理多种类型的请求: GET/POST/PUT/DELETE
- 函数的参数为一个配置对象
{ url: '', // 请求地址 method: '', // 请求方式GET/POST/PUT/DELETE params: {}, // GET/DELETE 请求的 query 参数 data: {}, // POST/PUT 请求的请求体参数}- 响应
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 let queryString = '' Object.keys(params).forEach((key) => { queryString += `${key}=${params[key]}&` }) if (queryString) { // 去除最后的'&' queryString = queryString.substring(0, queryString.length - 1) // 接到url url += '?' + queryString }
// 1. 执行异步Ajax请求 // 创建xhr对象 const request = new XMLHttpRequest() // 打开连接(初始化请求,没有请求) request.open(method, url, true) // 发送请求 if (method === 'GET' || method === 'DELETE') { request.send() // undefined } else if (method === 'POST' || method === 'PUT') { // 设置请求头,告诉服务器请求体的格式是json request.setRequestHeader( 'Content-Type', 'appliaction/json;charset=utf-8' ) // 发送json格式请求参数 request.send(JSON.stringify(data)) // 异步执行 }
// 绑定状态改变的监听 request.onreadystatechange = function () { // 同步执行 // 如果请求没有完成,直接结束 if (request.readyState !== 4) { return } // 如果响应状态码在[200, 300)之间代表成功,否则失败 const { status, statusText } = request if (status >= 200 && status <= 299) { // 2.1 如果请求成功,调用resolve() // 准备结果数据对象response const response = { data: JSON.parse(request.response), status, statusText, } resolve(response) } else { // 2.2 如果请求失败,调用reject() reject(new Error('request error status is ' + status)) } } })}使用测试
// 1. GET请求:从服务器端获取数据function testGet() { axios({ url: 'http://localhost:3000/posts', method: 'GET', params: { id: 1, xxx: 'abc', }, }).then( (response) => { console.log(response) }, (error) => { alert(error.message) } )}
// 2. POST请求:向服务器端添加数据function testPost() { axios({ url: 'http://localhost:3000/posts', method: 'POST', data: { title: 'json-server_post', author: 'typicode_post', }, }).then( (response) => { console.log(response) }, (error) => { alert(error.message) } )}// 3. PUT请求:服务器更新数据function testPut() { axios({ url: 'http://localhost:3000/posts/1', method: 'PUT', data: { title: 'json-server_put', author: 'typicode_put', }, }).then( (response) => { console.log(response) }, (error) => { alert(error.message) } )}
// 4. DELETE请求:服务器删除数据function testDelete() { axios({ url: 'http://localhost:3000/posts/2', method: 'delete', }).then( (response) => { console.log(response) }, (error) => { alert(error.message) } )}axios 的理解和使用
axios 是什么
- 前端最流行的 ajax请求库
- react/vue 官方都推荐使用 axios 发ajax 请求
- 文档: https://github.com/axios/axios
axios 特点
- 基于 xhr + promise 的异步 ajax请求库
- 浏览器端/node 端都可以使用
- 支持请求/响应拦截器
- 支持请求取消
- 请求/响应数据转换
- 批量发送多个请求
axios 常用语法
axios(config): 通用/最本质的发任意类型请求的方式axios(url[, config]): 可以只指定url 发get 请求axios.request(config): 等同于axios(config)axios.get(url[, config]): 发get 请求axios.delete(url[, config]): 发delete 请求axios.post(url[, data, config]): 发post 请求axios.put(url[, data, config]): 发put 请求axios.defaults.xxx: 请求的默认全局配置(method\baseURL\params\timeout…)axios.interceptors.request.use(): 添加请求拦截器axios.interceptors.response.use(): 添加响应拦截器axios.create([config]): 创建一个新的axios(它没有下面的功能)axios.Cancel(): 用于创建取消请求的错误对象axios.CancelToken(): 用于创建取消请求的 token 对象axios.isCancel(): 是否是一个取消请求的错误axios.all(promises): 用于批量执行多个异步请求axios.spread(): 用来指定接收所有成功数据的回调函数的方法
使用示例
GET 请求
// 为给定 ID 的 user 创建请求axios .get('/user?ID=12345') .then(function (response) { console.log(response) }) .catch(function (error) { console.log(error) })
// 可选地,上面的请求可以这样做axios .get('/user', { params: { ID: 12345, }, }) .then(function (response) { console.log(response) }) .catch(function (error) { console.log(error) })通过语法糖发送GET请求
axios(config)
// 发送 POST 请求axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone', },})
// 发送 GET 请求(默认的方法)axios('/user/12345')
// 发送 GET 请求(axios.get方法)axios.get('/user/12345')重点注意
axios.create(config)
- 根据指定配置创建一个新的 axios, 也就是每个新 axios 都有自己的配置
- 新 axios 只是没有取消请求和批量发请求的方法, 其它所有语法都是一致的
- 为什么要设计这个语法?
- 需求: 项目中有部分接口需要的配置与另一部分接口需要的配置不太一样, 如何处理(比如有多个baseURL需要指定)
- 解决: 创建2 个新axios, 每个都有自己特有的配置, 分别应用到不同要求的接口请求中
const instance = axios.create({ // instance是函数类型 baseURL: 'http://localhost:3000',})// 使用instance发Ajax请求instance({ url: '/posts',})instance.get('/posts')拦截器函数的调用顺序
- 说明: 调用
axios()并不是立即发送ajax 请求, 而是需要经历一个较长的流程 - 流程: 请求拦截器2 => 请求拦截器1 => 发ajax 请求 => 响应拦截器1 => 响应拦截器2 => 请求的回调
- 注意: 此流程是通过 promise 串连起来的, 请求拦截器传递的是
config, 响应拦截器传递的是response
// 添加两个请求拦截器(回调函数)axios.interceptors.request.use( (config) => { console.log('request interceptor1 onResolved()') // -----------2 return config }, (error) => { console.log('request interceptor1 onRejected()') return Promise.reject(error) })
axios.interceptors.request.use( (config) => { console.log('request interceptor2 onResolved()') // -----------1 return config }, (error) => { console.log('request interceptor2 onRejected()') return Promise.reject(error) })
// 添加两个响应拦截器axios.interceptors.response.use( (resopnse) => { console.log('response interceptor1 onResolved()') // -----------3 return resopnse }, (error) => { console.log('response interceptor1 onRejected()') return Promise.reject(error) })
axios.interceptors.response.use( (resopnse) => { console.log('response interceptor2 onResolved()') // -----------4 return resopnse }, (error) => { console.log('response interceptor2 onRejected()') return Promise.reject(error) })
axios .get('http://localhost:3000/posts') .then((response) => { console.log('data', response.data) //data Array(4) -------------5 }) .catch((error) => { cosole.log('error', error.message) })
// request interceptor2 onResolved()// request interceptor1 onResolved()// response interceptor1 onResolved()// response interceptor2 onResolved()// data Array(4)取消请求
基本流程
- 配置
cancelToken对象 - 缓存用于取消请求的
cancel函数 - 在后面特定时机调用
cancel函数取消请求 - 在错误回调中判断如果
error是cancel, 做相应处理
实现功能
在请求一个接口前, 取消前面一个未完成的请求
let cancel // 用于保存取消请求的函数function getProducts1() { // 在准备发请求前,取消未完成的请求 if (typeof cancel === 'function') { cancel('取消请求') } axios({ url: 'http://localhost:4000/products1', cancelToken: new axios.CancelToken(function executor(c) { // c是用于取消当前请求的函数 // 保存取消函数,用于之后可能需要取消当前请求 cancel = c }), }).then( (response) => { cancel = null console.log('请求1成功了', response.data) }, (error) => { if (axios.isCancel(error)) { console.log('请求1取消的错误', error.message) } else { // 请求出错了 cancel = null console.log('请求1失败了', error.message, error) // 请求1失败了 强制取消请求 Cancel {message: "强制取消请求"} } } )}
function getProducts2() { // 在准备发请求前,取消未完成的请求 if (typeof cancel === 'function') { cancel('取消请求') } axios({ url: 'http://localhost:4000/products2', cancelToken: new axios.CancelToken(function executor(c) { cancel = c }), }).then( (response) => { cancel = null console.log('请求2成功了', response.data) }, (error) => { if (axios.isCancel(error)) { console.log('请求2取消的错误', error.message) } else { cancel = null console.log('请求2失败了', error.message, error) } } )}function cancelReq() { // 执行取消请求的函数 if (typeof cancel === 'function') { cancel('强制取消请求') } else { console.log('没有可取消的请求') }}使用拦截器,减少重复代码
// 添加请求拦截器axios.interceptors.request.use((config) => { // 只写一个成功的回调 // 在准备发请求前,取消未完成的请求 if (typeof cancel === 'function') { cancel('取消请求') } // 添加一个cancelToken的配置 config.cancelToken = new axios.CancelToken(function executor(c) { // c是用于取消当前请求的函数 // 保存取消函数,用于之后可能需要取消当前请求 cancel = c }) return config})
// 添加响应拦截器axios.interceptors.response.use( (response) => { // 成功的回调 cancel = null return response }, (error) => { // 失败的回调 if (axios.isCancel(error)) { // 请求取消的错误 console.log('请求取消的错误', error.message) // 中断promise链 return new Promise(() => {}) } else { // 请求出错了 cancel = null // 将错误向下传递 // throw error return Promise.reject(error) } })
let cancel // 用于保存取消请求的函数function getProducts1() { axios({ url: 'http://localhost:4000/products1', }).then( (response) => { console.log('请求1成功了', response.data) }, (error) => { // 只用处理请求失败的情况,取消请求的错误不用处理 console.log('请求1失败了', error.message, error) } )}
function getProducts2() { axios({ url: 'http://localhost:4000/products2', }).then( (response) => { console.log('请求2成功了', response.data) }, (error) => { console.log('请求2失败了', error.message, error) } )}function cancelReq() { if (typeof cancel === 'function') { cancel('强制取消请求') } else { console.log('没有可取消的请求') }}文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
Ajax跨域
Ajax同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。 所…
2
Fetch
Ajaxfetch 是一种 HTTP 数据请求的方式,是 XMLHttpRequest 的一种替代方案。fetch 不是 ajax 的进一步封装,而是原生 js。Fetch 函数就是原生 js,没有使用 XMLHttpRequest 对象
3
原生Ajax
AjaxAjax 全称 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),既是一个对象,也是一种方法模式 AJAX 是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网…
4
react-hooks
reactReact 的核心是组件。v16.8 版本之前,组件的标准写法是类(class)。 任何一个组件,可以用类来写,也可以用钩子来写。下面是类的写法。 再来看钩子的写法,也就是函数。 官方推荐使用钩子(函数),而不是类。因为钩子更简洁,代码量少,用起来比较"轻",而类比较"重"。而且,钩子是函数,更符合…
5
关于 cesium 在 micro-app 下无法显示的问题
cesium基座:vite + vue3 子应用:vite + vue3 micro app v1.0.0 rc.29, cesium v1.135 子应用包含一个 cesium map,在基座打开子应用时,cesium 无法显示地图,但是 sence, sky box, model 都能正常显示,唯独地图不显…
随机文章随机推荐














