【Day01】你有封装过 axios 吗?主要是封装哪些方面?如何中断 axios 请求?
你有封装过 axios 吗?主要是封装哪些方面?如何中断 axios 请求?
- 一、封装过哪些方面?
- 1.1 http 封装
- 1.2 api 封装
- 1.2.1 总 api 接口的映射
- 1.2.2 建立一个 get_url.js,用于获取域名地址,实现环境切换可配置
- 1.2.3 单个模块接口定义
- 1.2.4 断网处理
- 1.3 将 api 挂载到全局
- 1.4 中断 axios 请求
一、封装过哪些方面?
基本逻辑如上,主要是对请求封装和 api 接口封装。
1.1 http 封装
http 封装,其实就是实例化一个 axios 对象,并对其进行一些配置:
设置请求超时
post 头设置
请求拦截
响应拦截
重复请求取消(这里涉及到了如何取消请求)
错误处理
断网处理
工具函数
import axios from 'axios' import router from '../router' import store from '../store/index' import { Toast } from 'vant'// 提示函数 const tip = msg => {Toast({message: msg,duration: 1000,forbidClick: true}) } // 跳转登录页,携带当前页面路由,登录后返回当前页面 const toLogin = () => {router.replace({path: '/login',query: {redirect: router.currentRoute.fullPath}}) } // 错误处理 const errorHandle = (status, other) => {switch (status) {// 未登录case 401:toLogin();break;// 403 token过期,清除token并跳转登录页case 403:tip('登录过期,请重新登录');localStorage.removeItem('token');store.commit(loginSuccess, null);setTimeout(() => {toLogin();}, 1000);break;//请求不存在case 404:tip('请求资源不存在');break;default:console.log(other)} }// 用于存储目前状态为pending的请求标识信息 let pendingRequest = [];// 取消请求-请求拦截中的处理 const CancelToken = config => {// 区别请求的唯一标识,这里用方法名+请求路径const requestMark = `${config.method} ${config.url}`;// 找当前请求的标识是否存在pendingRequest中,即是否重复请求了const markIndex = pendingRequest.findIndex(item => {return item.name === requestMark;});// 存在,即重复了if (markIndex > -1) {// 取消上个重复的请求pendingRequest[markIndex].cancel();// 删掉在pendingRequest中的请求标识pendingRequest.splice(markIndex, 1);}// (重新)新建针对这次请求的axios的cancelToken标识const CancelToken = axios.CancelToken;const source = CancelToken.source();config.cancelToken = source.token;// 设置自定义配置requestMark项,主要用于响应拦截中config.requestMark = requestMark;// 记录本次请求的标识pendingRequest.push({name: requestMark,cancel: source.cancel,});return config; };// 取消请求-响应拦截中的处理 const CancelTokenResponse = config => {// 根据请求拦截里设置的requestMark配置来寻找对应pendingRequest里对应的请求标识const markIndex = pendingRequest.findIndex(item => {return item.name === config.requestMark;});// 找到了就删除该标识markIndex > -1 && pendingRequest.splice(markIndex, 1); }// 创建axios实例 var instance = axios.create({timeout: 1000 * 12 })// 设置post请求头 instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';// 请求拦截器 instance.interceptors.request.use(config => {config = CancelToken(config);const token = store.state.token;token && (config.headers.Authorization = token);return config;},error => Promise.reject(error); ) // 响应拦截器 instance.interceptors.response.use(res => {// 请求结束就从pendingRequest删除请求标志CancelTokenResponse(res.config);return res.status === 200 ? Promise.resolve(res) : Promise.reject(res);},error => {const { response } = error;// 请求已经发出,返回结果不在2xx的范围if (response) {CancelTokenResponse(response.config);errorHandle(response.status, response.data.message);return Promise.reject(response);} else {// 断网情况,刷新重新获取数据if (!window.navigator.onLine) {store.commit('changeNetwork', false);} else {return Promise.reject(error);}}} )export default instance;
1.2 api 封装
api 封装,主要是用于单个模块所需要的接口进行管理。其中包括了
- 总 api 接口的映射
- 环境变量的切换
- 本地 mock 的功能
- 单个模块的接口列表
1.2.1 总 api 接口的映射
api 中定义一个 index.js ,用于所有模块接口的管理
//api接口统一出口 import user from "./user"; import productList from "./product"; //...export { user, productList };
1.2.2 建立一个 get_url.js,用于获取域名地址,实现环境切换可配置
get_url.js
import config from "@/config"; import urlMap from "@/config/urlMap";//api控制接口类型,1为远程接口,0为mock接口 export default function getUrl(url, api = 1) {return api === 0 ? urlMap[url] : config.apiDomain + url; }
新建一个配置文件夹 config,其中的 index 文件用于切换环境,urlMap 用于本地 mock 地址的映射
//config/index.js /*** 配置编译环境和线上环境之间的切换* 默认三套可以增添*/let apiDomain; switch (process.env.NODE_ENV) {case "dev":apiDomain = "https://www.dev.com";break;case "prod":apiDomain = "https://www.prod.com";break;case "test":apiDomain = "https://www.test.com";break; } export { apiDomain };
//urlMap.js /*** 远程接口地址和本地mock地址映射表* key:接口地址* value:本地地址*/ const mockBaseUrl = "http://rap2api.taobao.org/app/mock"; export default {"/user/login": mockBaseUrl + "/223948/login","/user/info": mockBaseUrl + "/223948/info","/user/logout": mockBaseUrl + "/223948/logout", };
1.2.3 单个模块接口定义
//产品列表接口
import axios from "@/http";
import getUrl from "@/api/get_url";const product = {// 新闻列表productList() {return axios({url: getUrl("/topics"),method: "get",});},// 新闻详情,演示productDetail(id, params) {return axios({url: getUrl(`/topic/${id}`),params: params,method: "get",});},// post提交login(data) {return axios({url: getUrl(`${base.sq}/accesstoken`),method: "post",data,});},//...更多接口
};export default product;
1.2.4 断网处理
http 封装中,当断网时,会对 Vue 的网络状态进行更新
在 App.vue 中,根据网络情况,判断是否需要加载断网组件
全局定义一个断网组件,实现跳转重新获取页面的操作
<!-- App.vue --> <template><div id="app"><div v-if="!network"><h3>我没网了</h3><div @click="onRefresh">刷新</div></div><router-view /></div> </template><script>import { mapState } from "vuex";export default {name: "App",computed: {...mapState(["network"]),},methods: {// 通过跳转一个空页面再返回的方式来实现刷新当前页面数据的目的onRefresh() {this.$router.replace("/refresh");},},}; </script>
http.js
中断网的时候,会更新 vue 中的 network 的状态。此时,根据 network 的状态来判断是否需要加载这个断网组件。当点击刷新的时候,我们通过跳转 refresh 页面,然后立即返回的方式,来实现重新获取数据的操作。因此,我们需要新建一个refresh.vue
页面,并在其beforeRouteEnter
钩子中再返回当前页面。// refresh.vue beforeRouteEnter (to, from, next) {next(vm => {vm.$router.replace(from.fullPath)}) }
1.3 将 api 挂载到全局
//main.js
import Vue from "vue";
import App from "./App";
import router from "./router"; // 导入路由文件
import store from "./store"; // 导入vuex文件
import api from "./api"; // 导入api接口Vue.prototype.$api = api; // 将api挂载到vue的原型上
1.4 中断 axios 请求
上面避免重复请求中,就使用到了 cancel token 取消请求,使用 CancelToken 工厂方法创建 cancel token
const CancelToken = axios.CancelToken;
const source = CancelToken.source();axios.get("/user/12345", {cancelToken: source.token,
}).catch(function (thrown) {if (axios.isCancel(thrown)) {console.log("Request canceled", thrown.message);} else {// 处理错误}
});axios.post("/user/12345",{name: "new name",},{cancelToken: source.token,}
);// 取消请求(message 参数是可选的)
source.cancel("Operation canceled by the user.");
【Day01】你有封装过 axios 吗?主要是封装哪些方面?如何中断 axios 请求?相关推荐
- axios 上传文件 封装_axios使用及封装
axios跨域及封装 1.安装 npm install axios --save 2.main.js引用 import axios from 'axios'; 3.axios基本用法 function ...
- axios的二次封装与async,await的配合使用?
前言:前些日子读文章,说是vue3.0会在明年下半年正式推出,改动的地方好像也不少,比如说vue3.x的代码库将会用typescript编写,并提供改进的 TypeScript 支持.变化还是很快的, ...
- axios如何二次封装
axios二次封装的五种方法 为什么要封装 axios 的 API 很友好,你完全可以很轻松地在项目中直接使用. 不过随着项目规模增大,如果每发起一次HTTP请求,就要把这些比如设置超时时间.设置请求 ...
- axios进行二次封装
Web开发中,我们最常用的HTTP库就是Axios了,它的底层基于Ajax进行封装,在浏览器端和服务端都可以使用.如果大家对一些API不是很熟悉可以参考官方地址,或者中文社区. 为什么要对ax ...
- Vue——axios的二次封装
文章目录 一.请求和传递参数 1.get 请求 2.post 请求 3.axios 请求配置 二.axios 的二次封装 1.配置拦截器 2.发送请求 三.API 的解耦 1.配置文件对应的请求 2. ...
- axios的使用和封装(九)
前言 axios 是一个基于 Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范.本章我们将介绍并演 ...
- axios介绍以及对axios进行二次封装
目录 一.axios基础 1.什么是axios? 2.axios的安装 3.axios常用配置项 4.axios和ajax的区别 二.使用axios发送请求 1. 发送get无参请求 2. 发送get ...
- axios的二次封装(详解)
一.首先让我们了解一下为什么要对axios进行二次封装? 1,代码封装,重用性高,减少代码量,减低维护难度. 2,统一处理一些常规的问题一劳永逸,如http错误. 3,拦截请求和响应,提前对数据进行处 ...
- axios 上传文件 封装_axios封装和传参
axios封装和传参 1.开发环境 vue+typescript 2.电脑系统 windows10专业版 3.在开发的过程中,我们会经常使用到 axios进行数据的交互,下面我来说一下,axios封装 ...
最新文章
- 使用Spring Data Redis操作Redis(集群版)
- 使用keepalived加lvs做负载均衡,访问后端的服务器,2分钟后超时,需要重新登录...
- oracle访问远程db2,如何在DB2与Oracle之间实现远程拷贝(二)
- 九度 1474:矩阵幂(二分法)
- spark的外排:AppendOnlyMap与ExternalAppendOnlyMap
- 使用python中的networkx来生成一个图
- 将ini文件内容读出
- WebViewJavascriptBridge 进行js 与native通信。
- Python爬虫番外篇之关于登录
- WebSocket消息推送(实现进行聊天)和WebSocket简介
- mysql必知必会样例表_《SQL必知必会》笔记1-样例表说明及建表语句
- 中山大学羽毛球场馆自动订场(Python+selenium+百度aip)
- 如何衡量和分配广告渠道?
- 坦克世界未能连接至更新服务器,坦克世界连接到更新服务器失败,小猪教您怎么解决坦克世界连接到更新服务器...
- 中国人民银行清算总中心CDA业务数据分析师培训正式开课
- 没有购买域名和服务器,怎么搭建网站?(一)
- 工作总结与个人职业经历
- 小程序学习与实践(一)
- 黑马就业班(02.JavaWeb+项目实战\18.LinuxNginx)
- QrCodeUtil--二维码工具类