axios的二次封装
Axios其实就是一个用于发送ajax请求的HTTP库,本质上是对AJAX的封装。
1.为什么要二次封装axios
当我们需要发送多个请求时,每次发请求需要携带一些特定的参数,比如要发送token字符串用来验证用户比如说当前页面用户必须登录成功当前用户作为一个合法身份才能去发请求,维护起来会非常的不方便;错误响应的统一处理;
此处,针对vue项目来进行axios的二次封装
开发环境"serve":"vue-cli-service serve"
2.先下载axios包
npm i axios
3.导入包
// 导入我们的axios库
import axios from 'axios';
4.位置和代码
在项目的src文件中新建一个utils文件专门用来放置二次封装axios的文件
utils文件下建一个request.js文件用来放置 axios二次封装的代码,再建一个api.js用来导入axios实例化对象service,封装请求
request.js文件
// axios二次封装
// 导入axios
import axios from 'axios'
// 导入Toast组件,轻提示
import {
Toast } from 'vant'
import $router from '../router'
// 实例化axios实例对象
var service = axios.create({
timeout: 10 * 1000,//设置请求超时时间
// baseURL: '/api',//请求地址的基准路径
// 假设在代码中发请求/user/list,实际发出的请求是/api/user/list
// baseURL: 'http://waimai.yantianfeng.com/',//请求地址的基准路径
baseURL: process.env.VUE_APP_BASE_API,//请求地址的基准路径
//在开发环境下, process.env.VUE_APP_BASE_API 获取的是 .env.development 文件中的 VUE_APP_BASE_API 的值, 可以正常使用代理解决跨域问题(代理配置是生效的).
//在生产环境下, process.env.VUE_APP_BASE_API 获取的是 .env.production 文件中的 VUE_APP_BASE_API 的值, 这时的代理配置是无效( 请求如果存在跨域, 必须由服务器解决 ).
})
// 设置请求拦截器
service.interceptors.request.use(
(config) => {
//请求发出前会立即自动执行的回调函数
// 统一设置请求头(设置请求头头数据的格式,看服务器是)
config.headers['Authorization'] = 'Bearer' + ' ' + localStorage.getItem('token');
// 显示loading; duration: 将所有 Toast 的展示时长设置为 0 毫秒
Toast.loading({
message: 'loading...', duration: 0 })
return config;
},
(error) => {
//请求发出前,发生错误的回调函数
//Promise.reject(error);方法返回一个带有拒绝原因(error参数)的Promise对象
return Promise.reject(error);
},
)
// 设置响应拦截器
service.interceptors.response.use(
(res) => {
//请求从服务器返回前会立即自动执行的回调函数
Toast.clear(); //隐藏loading
return res;//一定要return如果忘记return就意味着服务器给你响应的所有数据接收不到都会丢失
},
(error) => {
//请求从服务器返回前,发生错误的回调函数
// error是响应错误的对象
Toast.clear(); //隐藏loading
if (error.response.status == 401) {
Toast.fail({
message: "身份认证失败,登陆过期,请重新登录!" })
// 移除本地存储中的请求头
localStorage.removeItem('token');
$router.push('/login');//跳转到登录页
}
else if (error.response.status == 404) {
Toast.fail({
message: "访问路径有误!" })
}
else if (error.response.status == 500) {
Toast.fail({
message: "服务器内部错误!" })
}
return Promise.reject(error);
},
)
// 抛出axios实例对象
export default service;
api.js文件
// 导入axios实例化对象service
import service from "./request";
// 一个请求,封装成一个函数
// 将整个项目中的所有请求都集中管理到这个api.js文件中
// service.get('/shop/list')作用的返回值是一个promise对象
// get类型的请求
export function shop_list(params = {
}) {
return service.get('/shop/list', {
params })
}
//post类型的请求
export function user_login(params = {
}) {
return service.post('/user/login', params)
}
5.相关的配置文件
这三个文件都是和src并列的,前两个需要自己去创建,第三个文件是项目中带的需要去配置
.env.development文件
# 这里用于定义在开发环境下需要使用的环境变量,这些变量默认以 VUE_APP_ 开头
# 定义在这个文件中的环境变量,在生产环境下不起作用
VUE_APP_BASE_API = /api
.env.production文件
# 这里用于定义在生产环境下需要使用的环境变量,这些变量默认以VUE_APP_开头
# 定义在这个文件中的环境变量,在开发环境下不起作用
VUE_APP_BASE_API = http://waimai.yantianfeng.com/
vue.config.js文件中的配置
const {
defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
publicPath: './',//确保打包后的所有静态资源(css/js/图片)在html文档中以 ./开头 , 可以正常加载资源文件.
devServer: {
//设置开发服务器
proxy: {
//设置代理
//这个地方设置 '/api' 是以为项目的接口都是以/api开头的
'/api': {
//以'api'开头的请求会自动转发到target表示的服务器
target: "http://waimai.yantianfeng.com/",//设置目标服务器地址
changeOrigin: true,//允许跨域
pathRewrite: {
}//重写请求地址
},
//如果项目的接口 一部分以/user开头, 一部分以/shop开头, 一部分以/address开头 , 设置多个代理是很麻烦的,
// '/user':{
// target:'http://waimai.yantianfeng.com/',
// changeOrigin:true,
// pathRewrite:{}
// },
// '/shop':{
// target:'http://waimai.yantianfeng.com/',
// changeOrigin:true,
// pathRewrite:{}
// },
// '/address':{
// target:'http://waimai.yantianfeng.com/',
// changeOrigin:true,
// pathRewrite:{}
// },
//可以临时给这些接口添加统一的前缀 /api2 , 这时所有的接口变成
// /api2/user/xxx
// /api2/shop/xxx
// /api2/address/xxx
// 现在我(程序员) 只需要设置一个代理即可, 类似下面这样
// '/api2':{
// target:'http://waimai.yantianfeng.com/',
// changeOrigin:true,
// pathRewrite:{ //路径重写
// '^/api2':'/'
// }
// }
//但是由于实际的接口是不包括 /api2 这部分的. 这时可以用pathRewrite设置路径重写,去掉/api2这部分.
//最终发出去的请求地址就是: /user/xxx /shop/xxxx /address/xxxx
}
}
})