前端vueaxiosaxios不入门直接起飞
caolibin
Axios是什么?
Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http
模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests
1.安装
使用npm安装:
使用yarn安装:
2.包装统一请求工具
因为后端地址是一样的,假设是localhost:8080,只是请求路径不一样,我们可以定义一个baseURL,此处使用/api
是为了解决跨域问题
1.先包装一个工具request.js
import axios from "axios";
const baseURL = "/api"; const instance = axios.create({baseURL}); export default instance;
|
2.在vite.config.js
文件中添加配置,将/api
删除,替换为http://localhost:8080
,这样就相当于使用前端服务发送请求而不是浏览器,解决了跨域请求问题
export default defineConfig({ plugins: [ vue(), AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ElementPlusResolver()], }), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, server: { host: 'localhost', port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } }, })
|
3.拦截器
这是axios发送请求的一个示例,项目中会有很多这样的请求要发送,我们会发现发送请求和接收响应数据之前,我们都会做一些相同的事情,比如,发送请求之前我们都会给请求头中带上token,接收响应时我们都会先判断状态码,我们不妨将这些动作用一个统一的函数来实现,这就需要使用拦截器
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
|
这是一个响应拦截器的示例,axios会自动适配响应的http状态码为4xx或5xx的请求为失败回调,在失败回调中我们可以对各种状态码的失败回调统一处理,成功回调中如果自定义的code为0也表示有错误,这种统一处理的方式类似于Spring中的AOP
instance.interceptors.response.use( (result) => { if (result.data.code = 0) { ElMessage.error(result.data.msg); return Promise.reject(result); } return result.data; }, (error) => { if (error.response) { const code = error.response.status; if (code = 401) { ElMessage({message: '请先登录!', type: "error",}); router.push('/login'); } else if (code = 419) { ElMessage.error("身份已过期,请重新登录!"); router.push('/login'); } else { ElMessage.error("服务器异常!" + code); } } return Promise.reject(error); } );
|
这是一个请求拦截器的示例,在发送请求之前先判断是否有token,如果有就在请求头上带上token再发送请求,否则跳转到登录页面,当然,登录和注册请求都不需要token,可以直接发送请求
instance.interceptors.request.use( (config) => { if (config.url.endsWith('/login') || config.url.endsWith('/register')) { return config; } const token = tokenStore.token; if (token != null) { config.headers['token'] = token; } else { router.push('/login'); ElMessage({message: '请先登录!', type: "error",}); return Promise.reject('token不存在!'); } return config; }, (err) => { return Promise.reject(err); } );
|
4.完整axios包装工具示例
import axios from "axios"; import {ElMessage} from "element-plus"; import router from "@/router"; import {useTokenStore} from "@/stores/token.js";
const baseURL = "/api"; const instance = axios.create({baseURL}); const tokenStore = useTokenStore();
instance.interceptors.response.use( (result) => { if (result.data.code = 0) { ElMessage.error(result.data.msg); return Promise.reject(result); } return result.data; }, (error) => { if (error.response) { const code = error.response.status; if (code = 401) { ElMessage({message: '请先登录!', type: "error",}); router.push('/login'); } else if (code = 419) { ElMessage.error("身份已过期,请重新登录!"); router.push('/login'); } else { ElMessage.error("服务器异常!" + code); } } return Promise.reject(error); } );
instance.interceptors.request.use( (config) => { if (config.url.endsWith('/login') || config.url.endsWith('/register')) { return config; } const token = tokenStore.token; if (token != null) { config.headers['token'] = token; } else { router.push('/login'); ElMessage({message: '请先登录!', type: "error",}); return Promise.reject('token不存在!'); } return config; }, (err) => { return Promise.reject(err); } );
export default instance;
|
在其他接口文件中导入使用,因为使用的是export default instance
默认导出的,所以导入时可以自定义名字,这个文件中定义为request
,其实就是instance
实例
import request from "@/util/request.js";
const logoutService = function () { return request.delete('/logout'); }
export {logoutService}
|