网站首页 > 技术文章 正文
axios封装
虽然vite在很多配置方面和vue-cli极其相似,但是区别的地方还是需要注意的。在给axios封装过程中一般需要区分开发或者生产环境,因为开发与生产环境对应的服务器不一致,比如接口地址。
vue-cli内置的process.env.NODE_ENV的可以判断当前的环境是development还是production,而vite使用的方法是import.meta.env.NODE_ENV,所以针对vue-cli和vite环境下的封装需要注意这点:
// src/request/axios.js
import axios from 'axios'
import qs from 'qs'
// import router from '@/router'//路由文件
// import { Message } from 'element-ui'
let api_base_url = ''
// vite
if (import.meta.env.NODE_ENV === 'development') {
api_base_url = 'https://client.doubilm.com'
} else if (import.meta.env.NODE_ENV === 'production') {
api_base_url = 'https://client.doubilm.com'
}
// 如果是vue-cli
//if (process.env.NODE_ENV === 'development') {
// api_base_url = 'https://client.doubilm.com'
//} else if (import.meta.env.NODE_ENV === 'production') {
// api_base_url = 'https://client.doubilm.com'
//}
/* 防止请求重复
1. 我们需要对所有正在进行中的请求进行缓存。在请求发起前判断缓存列表中该请求是否正在进行,如果有则取消本次请求。
2.在任意请求完成后,需要在缓存列表中删除该次请求,以便可以重新发送该请求
*/
//正在请求的API队列
let requestList = []
/**
* @name: 阻止请求
* @param {array} requestList 当前API请求队列
* @param {string} currentUrl 当前请求API
* @param {function} cancelFn 请求中断函数
* @param {string} errorMsg 中断错误信息
*/
const stopRepeatRequest = (requestList, currentUrl, cancelFn, errorMsg) => {
const errorMessage = errorMsg || '请求出错拥堵'
for (let i = 0; i < requestList.length; i++) {
if (requestList[i] === currentUrl) {
cancelFn(errorMessage)
return
}
}
// 将当前请求加入执行队列
requestList.push(currentUrl)
}
/**
* @name: 请求完成后从队列删除当前请求
* @param {array} requestList 当前API请求队列
* @param {string} currentUrl 当前请求API
*/
const allowRequest = (requestList, currentUrl) => {
for (let i = 0; i < requestList.length; i++) {
if (requestList[i] === currentUrl) {
requestList.splice(i, 1)
break
}
}
}
let instance = axios.create({
timeout: 1000 * 80,
baseURL: api_base_url,
// headers: {
// 'Content-Type': 'application/json;charset=UTF-8',
// },
})
// instance.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
// instance.defaults.responseType = 'json'
// instance.defaults.withCredentials = true
instance.defaults.transformRequest = [
data => {
return qs.stringify(data)
}
]
instance.defaults.validateStatus = function () {
// return status >= 200 && status < 400; // 200- 399 resolve 其他状态码 reject
// 如果在响应拦截设置了状态码判断,这里设置返回 true
return true
}
// 请求拦截器
instance.interceptors.request.use(
config => {
// 设置cancelToken
let cancelFn = null;
config.cancelToken = new axios.CancelToken(function (c) {
cancelFn = c
})
//阻止重复请求
stopRepeatRequest(requestList, config.url, cancelFn, `不要连续请求:${config.url},速度太快了`)
//{url: "/slides", method: "get", headers: {…}, baseURL: "http://api.hzwlb.org", transformRequest: Array(1), responseType: "json",…}
return config
},
error => {
// Message.error({ message: '请求超时!' })
// console.log('请求超时!');
return Promise.reject(error)
}
)
// 响应拦截器即异常处理
// 服务器 Response 对象
instance.interceptors.response.use(
response => {
//不得重复发送
setTimeout(() => {
allowRequest(requestList, response.config.url), 1000
})
// {data: {…}, status: 200, statusText: "OK", headers: {…}, config: {…}, request:{…}}
let data = response.data //响应的数据部分(服务器返回部分)
let status = response.status //标准状态码
if (status === 200) { //如果响应正常则放行 数据
return Promise.resolve(data)
}
else if (status >= 400 && status <= 499) {
// Message.error({ message: '客户端请求错误!' })
console.log('客户端请求错误码:', status);
return
}
else {
//其他错误
// Message.error({ message: response.statusText })
// console.log('服务器错误,错误码:', status);
// return Promise.reject(response)
if (axios.isCancel(thrown)) {
console.log(thrown.message);
} else {
return Promise.reject(response)
}
}
},
error => {
console.log('响应错误信息:')
console.log(error.message)
}
)
let api = {}
api.get = function (url) {
return new Promise((resolve, reject) => {
instance
.get(url)
.then(response => {
resolve(response)
})
.catch(error => {
reject(error)
})
})
}
api.post = function (url, data) {
return new Promise((resolve, reject) => {
instance
.post(url, data)
.then(response => {
resolve(response)
})
.catch(error => {
reject(error)
})
})
}
export default api
增加了对重复请求的处理
API调用
再和上面同级目录内创建一个聚合API的文件api.js
import api from "./axios.js"
export const getEmoticon = () => api.get(`/api/emoticon/recommend/list`)
组件内再引入相关的API
import { getEmoticon } from "../request/api.js";
async function Emoticon() {
let result = await getEmoticon();
}
vite跨域的配置(代理跨域)
import { defineConfig } from 'vite'
const { resolve } = require('path')
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()], // 配置需要使用的插件列表,这里将vue添加进去
// 配置文件别名 vite1.0是/@/ 2.0改为/@
// 这里是将src目录配置别名为 /@ 方便在项目中导入src目录下的文件
resolve: {
alias: {
"/@": resolve(__dirname, 'src')
}
},
// 强制预构建插件包
optimizeDeps: {
include: ['axios'],
},
// 打包配置
build: {
target: 'modules',
outDir: 'dist', //指定输出路径
assetsDir: 'assets', // 指定生成静态资源的存放路径
minify: 'terser' // 混淆器,terser构建后文件体积更小
},
// 本地运行配置,及反向代理配置
server: {
cors: true, // 默认启用并允许任何源
open: true, // 在服务器启动时自动在浏览器中打开应用程序
port: 8080,
//反向代理配置,注意rewrite写法,开始没看文档在这里踩了坑
proxy: {
'^/api': {
target: 'https://client.doubilm.com', //代理接口
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})
- 上一篇: 前端常见面试 - 请求篇 前端面试常见题
- 下一篇: 开源跨平台的http请求解决方案——Fly.js
猜你喜欢
- 2024-10-17 简书看到的技术文档,非常详细解释了axios技术,值得收藏
- 2024-10-17 全面分析前端的网络请求方式 前端网络请求框架
- 2024-10-17 一步一步学测试平台开发-Vue restful请求
- 2024-10-17 前端面试29:什么是fetch?fetch与20年前的ajax有什么不同?
- 2024-10-17 手把手教你全面分析前端如何网络请求方式
- 2024-10-17 实战:整合VueJS、Axios和Jacksons实现JAVA EE 下的数据持久化
- 2024-10-17 前端基础面试:axios的特点和基本使用方法以及拦截器的使用方法
- 2024-10-17 在React项目中使用Axios react-intl
- 2024-10-17 前端金三银四面试必备八股文——JavaScript
- 2024-10-17 Axios是什么?用在什么场景?如何使用?
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)