在项目中一般会使用 axios - 基于 Promise 的网络请求库 来进行网络请求。
将 axios 进行适当的封装,在使用上可以事半功倍。
安装axios
npm install axios
基本使用
导入 axios 后就可以直接进行网络 api 请求,不过为了方便维护,处理跨域等问题会封装后再使用。
promise用法
import axios from "axios";
// get请求
axios.get("http://192.168.1.90:4000/api/login/sms?tel=13333333333")
import axios from "axios";
// get请求
axios
.get("http://192.168.1.90:4000/api/login/sms?tel=13333333333")
.then((res) => {
// 处理成功情况
console.log(res)
})
.catch(function (err) {
// 处理错误情况
console.log(err)
})
.finally(function () {
// 总是会执行
})
// post请求
axios
.post("http://192.168.1.90:4000/api/login", {
tel: 13333333333,
code: 1234
})
.then(res => {
console.log(res.data)
})
async/await用法
import axios from "axios";
async function getSms() {
try {
const res = await axios.get("http://192.168.1.90:4000/api/login/sms?tel=13333333333")
console.log(res);
} catch (err) {
console.error(err);
}
}
视频🎞️
创建实例
// 创建axios实例
let baseURL= ""
if (import.meta.env.DEV) { // 开发环境
baseURL= "http://192.168.1.90:4000"
} else { // 生产环境
baseURL= "http://xxx.com"
}
const service = axios.create({
// 配置URL公共部分,如果要解决开发环境跨域问题这里不用配,在vite.config.json中配置
baseURL: baseURL,
// 设置请求超时时间单位毫秒
timeout: 15000,
// 设置请求头
headers: {'X-Custom-Header': 'foobar'}
})
请求拦截器
axios 的请求拦截器,允许你在发出 HTTP 请求之前,对请求进行预处理或修改。
一般可以进行:
- 统一处理请求头:如在请求头中添加 token 或者其他信息。
- 请求参数统一格式化:如对查询参数进行额外的校验或格式化。
- 错误处理。
service.interceptors.request.use(
(config) => {
// 在这里可以对所有请求进行预处理,比如往请求头中添加token
const token = localStorage.getItem('authToken');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
// 如果一切正常,则必须返回config对象或者Promise.resolve(config)
return config
},
(error) => {
// 对请求错误做些什么
// 返回Promise.reject(error),这样会触发后续的错误处理器
Promise.reject(error)
},
)
响应拦截器
axios 的响应拦截器会在接收到 HTTP 响应之后、调用者实际拿到响应结果之前介入处理。
一般可以进行:
- 统一处理响应结果:如将后端返回的数据结构标准化,或者对某些特定的状态码进行统一处理。
- 错误处理:针对非成功状态码(如 401、403、500 等)进行特殊处理,如用户未登录时重定向到登录页面、显示全局错误提示等。
- 数据缓存策略,对于某些特定类型的请求结果进行缓存,减少不必要的重复请求。
service.interceptors.response.use(
(res) => {
let data = res.data
if (data.code !== 0) {
Toast.error(data.msg)
return Promise.reject(data)
}
return data // (相录于返回的 res 被自动 剥掉一层,变成 data 字段)
},
(error) => {
if (error?.request?.status === 401 && location.pathname !== "/login") {
// 当用户登录超时时,清空登录状态
const store = useUsersStore()
store.user = {}
// 跳转到登录页
if (error.config.url !== "/api/user/info") {
sessionStorage.setItem("LOGIN_REDIRECT", location.hash.substr(1))
router.replace("/login")
}
}
return Promise.reject(error)
},
)
最终代码
import axios from "axios"
import {Toast} from "@/until/toast"
import {useUsersStore} from "@/store/user"
import router from "@/router"
axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8"
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
// baseURL: 'http://localhost:4001',
// 超时
timeout: 15000,
})
// request拦截器
service.interceptors.request.use(
(config) => {
// 在这里可以对所有请求进行预处理,比如往请求头中添加token
const token = localStorage.getItem('authToken');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
// 如果一切正常,则必须返回config对象或者Promise.resolve(config)
return config
},
(error) => {
// 对请求错误做些什么
// 返回Promise.reject(error),这样会触发后续的错误处理器
Promise.reject(error)
},
)
// 响应拦截器
service.interceptors.response.use(
(res) => {
let data = res.data
if (data.code !== 0) {
Toast.error(data.msg)
return Promise.reject(data)
}
return data // (相录于返回的 res 被自动 剥掉一层,变成 data 字段)
},
(error) => {
if (error?.request?.status === 401 && location.pathname !== "/login") {
// 当用户登录超时时,清空登录状态
const store = useUsersStore()
store.user = {}
// 跳转到登录页
if (error.config.url !== "/api/user/info") {
sessionStorage.setItem("LOGIN_REDIRECT", location.hash.substr(1))
router.replace("/login")
}
}
return Promise.reject(error)
},
)
export default service
在项目中使用
在 src 下创建 api 目录,目录下创建相应模块的 js 文件 ( login.js、user.js… ),并且创建的 api 方法以 Api 结尾,这样方便与普通方法区分。
如果需要修改 api 路径,或者参数需要统一调整就可以在这里进行处理。
// /src/api/login.js
import request from "@/until/request"
// 发送登录验证码
export function sendSmsApi(tel) {
// 这里的url不要写全从/api开始即可,方便配置环境切换/跨域
return request.get("/api/login/sms?tel=" + tel)
}
// ... 其它api
直接导入需要使用的 api 方法 ( sendSmsApi ) 进行使用
// /src/views/login.vue
<script setup>
import {ref} from "vue"
import {sendSmsApi} from "@/api/login"
const tel = ref(null)
// 发送验证码
function sendSmsCode() {
sendSmsApi(tel.value)
.then((res) => {
console.log(res.msg)
})
}
</script>