封装方式一

import axios from 'axios'
import qs from 'qs'
import { Toast } from 'vant'
import Lockr from 'lockr' axios.defaults.timeout = 30000
axios.defaults.baseURL = import.meta.env.VITE_HOST
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded' // http request
axios.interceptors.request.use((config) => {
config.headers.refererUrl = window.location.href
config.headers.authKey = Lockr.get('authKey')
config.headers.sessionId = Lockr.get('sessionId')
// 请求头参数处理
config.data = qs.stringify(config.data)
return config
}, (error) => {
return Promise.reject(error)
}) // http response
axios.interceptors.response.use((res) => {
if (res.status && res.status === 200 && res.data.code !== 200) {
if (res.data.code === 101) {
window.location.href = `${window.location.origin}${import.meta.env.VITE_HREF}/login${res.data.url?`?return_url=${res.data.url}&type=${res.data.type}`:''}`
} else if (res.data.msg && res.data.msg !== '') {
Toast(res.data.msg)
} else if (res.data.code === 203) {
return false
} else {
Toast('系统错误')
}
}
return res
}, (error) => {
if (!error.response && error.message) {
Toast('请求超时,请检查网络,刷新后重试')
} else {
Toast('系统错误')
}
return Promise.reject(error)
})
export default axios /**
* 封装get方法
* @param url
* @param params
* @returns {Promise}
*/ export function get (url: any, params: Object = {}) {
params.t = new Date().getTime()
return new Promise((resolve, reject) => {
axios.get(url, {
params: params
})
.then(response => {
resolve(response.data)
})
.catch(err => {
reject(err)
})
})
} /**
* 封装post请求
* @param url
* @param data
* @returns {Promise}
*/ export function post (url: any, data: Object = {}) {
return new Promise((resolve, reject) => {
axios.post(url, data)
.then(response => {
resolve(response.data)
}, err => {
reject(err)
})
.catch(err => {
reject(err)
})
})
} /**
* 封装delete方法
* @param url
* @param params
* @returns {Promise}
*/ export function doDelete (url: any, params: Object = {}) {
return new Promise((resolve, reject) => {
axios.delete(url, {
params: params
})
.then(response => {
resolve(response.data)
})
.catch(err => {
reject(err)
})
})
} /**
* 封装patch请求
* @param url
* @param data
* @returns {Promise}
*/ export function patch (url: any, data: Object = {}) {
return new Promise((resolve, reject) => {
axios.patch(url, data)
.then(response => {
resolve(response.data)
}, err => {
reject(err)
})
.catch(err => {
reject(err)
})
})
} /**
* 封装put请求
* @param url
* @param data
* @returns {Promise}
*/ export function put (url: any, data: Object = {}) {
return new Promise((resolve, reject) => {
axios.put(url, data)
.then(response => {
resolve(response.data)
}, err => {
reject(err)
})
.catch(err => {
reject(err)
})
})
}

使用方式

import { get, post } from '@/utils/request.ts'
get(url).then(...)
post(url).then(...)
...

封装方式二

// http.ts
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
import qs from 'qs' /* const showStatus = (status: number) => {
let message = ''
switch (status) {
case 400:
message = '请求错误(400)'
break
case 401:
message = '未授权,请重新登录(401)'
break
case 403:
message = '拒绝访问(403)'
break
case 404:
message = '请求出错(404)'
break
case 408:
message = '请求超时(408)'
break
case 500:
message = '服务器错误(500)'
break
case 501:
message = '服务未实现(501)'
break
case 502:
message = '网络错误(502)'
break
case 503:
message = '服务不可用(503)'
break
case 504:
message = '网络超时(504)'
break
case 505:
message = 'HTTP版本不受支持(505)'
break
default:
message = `连接出错(${status})!`
}
return `${message},请检查网络或联系管理员!`
} */ const service = axios.create({
baseURL: import.meta.env.VITE_HOST,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
// 是否跨站点访问控制请求
withCredentials: false,
timeout: 30000,
transformRequest: [(data) => {
data = JSON.stringify(data)
return data
}],
validateStatus() {
// 使用async-await,处理reject情况较为繁琐,所以全部返回resolve,在业务代码中处理异常
return true
},
transformResponse: [(data) => {
if (typeof data === 'string' && data.startsWith('{')) {
data = JSON.parse(data)
}
return data
}]
}) // 声明一个 Map 用于存储每个请求的标识 和 取消函数
const pending = new Map()
/**
* 添加请求
* @param {Object} config
*/
const addPending = (config: AxiosRequestConfig) => {
const url = [
config.method,
config.url,
qs.stringify(config.params),
qs.stringify(config.data)
].join('&')
config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
if (!pending.has(url)) { // 如果 pending 中不存在当前请求,则添加进去
pending.set(url, cancel)
}
})
}
/**
* 移除请求
* @param {Object} config
*/
const removePending = (config: AxiosRequestConfig) => {
const url = [
config.method,
config.url,
qs.stringify(config.params),
qs.stringify(config.data)
].join('&')
if (pending.has(url)) { // 如果在 pending 中存在当前请求标识,需要取消当前请求,并且移除
const cancel = pending.get(url)
cancel(url)
pending.delete(url)
}
} /**
* 清空 pending 中的请求(在路由跳转时调用)
*/
export const clearPending = () => {
for (const [url, cancel] of pending) {
cancel(url)
}
pending.clear()
} // 请求拦截器
service.interceptors.request.use((config: AxiosRequestConfig) => {
removePending(config) // 在请求开始前,对之前的请求做检查取消操作
addPending(config) // 将当前请求添加到 pending 中
// let token = localStorage.getItem('token')
// if(token){
// config.headers.Authorization = `${token}`;
// }
return config
}, (error) => {
// 错误抛到业务代码
error.data = {}
error.data.msg = '服务器异常,请联系管理员!'
return Promise.resolve(error)
}) // 响应拦截器
service.interceptors.response.use((response: AxiosResponse) => { removePending(response) // 在请求结束后,移除本次请求
const status = response.status
let msg = ''
if (status < 200 || status >= 300) {
// 处理http错误,抛到业务代码
// msg = showStatus(status)
if (typeof response.data === 'string') {
response.data = { msg }
} else {
response.data.msg = msg
}
} return response
}, (error) => {
if (axios.isCancel(error)) {
console.log('repeated request: ' + error.message)
} else {
// handle error code
// 错误抛到业务代码
error.data = {}
error.data.msg = '请求超时或服务器异常,请检查网络或联系管理员!'
// ElMessage.error(error.data.msg)
}
return Promise.reject(error)
}) export default service

使用方式

import axios from '@/utils/http.ts'
axios(url, {
method: 'get',
responseType: 'json',
params: {},
}).then(res => {
console.warn('tag', res)
})

方式二参考:Vue3+TypeScript封装axios并进行请求调用

注意事项: 谨慎添加withCredentials为true

vue3.0+vite+ts项目搭建-axios封装(六)的更多相关文章

  1. vue3.0+vite+ts项目搭建--基础配置(二)

    集成vue-router 使用yarn yarn add vue-router@next --save 安装完成之后在src目录下创建文件夹router/index.ts,创建完成之后需要在Vue-R ...

  2. vue3.0+vite+ts项目搭建--初始化项目(一)

    vite 初始化项目 使用npm npm init vite@latest 使用yarn yarn create vite 使用pnpm pnpx create-vite 根据提示输入项目名称,选择v ...

  3. vue3.0+vite+ts项目搭建--vite.config.ts配置(三)

    vite.config.ts配置 配置路径处理模块 安装ts的类型声明文件 yarn add @types/node -D 通过配置alias来定义路径的别名 resolve: { alias: { ...

  4. vue3.0+vite+ts项目搭建-postcss-pxtorem 实现移动自适应(五)

    这里不考虑大屏,所以不做amfe-flexible的配置 首先是安装依赖 yarn add postcss-loader postcss-pxtorem -D yarn add autoprefixe ...

  5. vue3.0+vite+ts项目搭建-分环境打包(四)

    分环境打包配置 新建.env.dev(或者.env) VITE_NODE_ENV = 'dev' VITE_HOST = 'http://local.host.com' 执行yarn dev ,控制台 ...

  6. vue3.0+vite+ts项目搭建(报错处理)

    报错一 warning package.json: No license field$ vue-tsc --noEmit && vite build 解决方案,添加这两行,只添加一个是 ...

  7. vite + ts 快速搭建 vue3 项目 以及介绍相关特性

    博客地址:https://ainyi.com/98 Vue3.0,One Piece 接下来得抽空好好学习了 vite 尤大在 Vue 3.0 beta 直播中推荐了 vite 的工具,强调:针对Vu ...

  8. vue3.0脚手架 创建项目

    1.下载node最新稳定版本,并且安装 2.安装好之后,在cmd或者terminal下, 使用npm -v 查看当前npm版本,验证是否安装成功 3.安装成功后,运行 npm i -g @vue/cl ...

  9. webpack 4 :从0配置到项目搭建

    webpack4发布以来,我写项目都是用脚手架,即使再简单的项目,真的是really shame..虽然道听途说了很多 webpack4 的特性,却没有尝试过,因为它给人的感觉就是,em...很难.但 ...

随机推荐

  1. Tableau如何绘制堆叠柱状图

    一.将类别,子类别拖拽至列上 二.将度量值拖拽至行上 三.将度量名称拖拽至筛选器上,右键度量名称,编辑筛选器,选择销售额 四.将事先准备的目标销售额拖拽至度量值 五.将度量名称拖拽至标记,分别以颜色和 ...

  2. 01-gevent完成多任务

    gevent完成多任务 一.原理 gevent实现多任务并不是依靠多进程或是线程,执行的时候只有一个线程,在遇到堵塞的时候去寻找可以执行的代码.本质上是一种协程. 二.代码实现 import geve ...

  3. 象群游牧算法--EHO

    象群游牧算法的数学模型 象群的游牧行为非常复杂,但是其中一些行为可以帮助我们寻找全局最优解和局部最优解.对此,进行数学建模为: (1) 象群的每个部落都有固定数目的大象: (2) 每次迭代中,部落中都 ...

  4. 分组依据(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 [视图]选项卡下,[筛选器]楼下,住着个[分组依据]. 这个功能,说白了,就是指定个"组",把同一组的 ...

  5. CF23A You're Given a String... 题解

    Content 给定一个长度为 \(n\) 的字符串,求出至少出现两次的最长子串的长度. 数据范围:\(1\leqslant n\leqslant 100\). Solution 我们直接暴力求出每个 ...

  6. ftp:500 Illegal PORT command. 425

    局域网用FTP命令访问外网的FTP SERVER,执行任何命令(如dir,ls,put,get)总是报下面的错误ftp:500 Illegal PORT command. 425ftp:Use POR ...

  7. 客户通过新型网络访问Web服务

  8. vue+el-element中根据文件名动态创建dialog的方法

    背景 在项目中使用对话框的通常做法是把对话框封装成组件,在使用的地方引入,然后添加到template,使用visible.sync控制对话框的显示/隐藏,监听confirm事件处理用户点击确定.如下: ...

  9. SpringBoot基础篇(一)

    1.前言 什么是SpringBoot:springboot是当下一套流行的J2EE框架.借助微服务的思想.将业务分成一个个的服务.通过spring-cloud进行整合.最后通过spring-data进 ...

  10. 使用JS对字符串进行MD5加密

    md5.js /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorith ...