完整代码
import storageService from '@/service/storageService';
import axios from 'axios';
import store from '@/store';
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_URL,
timeout: 5000,
});
service.interceptors.response.use((response) => {
return response;
}, async (error) => {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
setTimeout(() => {
originalRequest._retry = true;
store.commit('SET_TOKEN', '');
storageService.set(storageService.USER_TOKEN, '');
store.commit('SET_USERINFO', '');
storageService.set(storageService.USER_INFO, '');
localStorage.removeItem('Partition');
window.location.reload();
}, 2000);
}
return Promise.reject(error);
});
export default service;
详解
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_URL,
timeout: 5000,
});
这段代码创建了一个axios
实例,该实例用于发送HTTP请求
-
const service = axios.create({ ... });
:这行代码使用了axios.create
方法来创建一个新的axios
实例,该实例将具有一组特定的配置选项。这个新创建的实例被赋值给名为service
的常量。 -
baseURL: process.env.VUE_APP_BASE_URL,
:baseURL
选项指定了所有请求的基础URL。当你使用这个service
实例发送请求时,请求的URL将与此基础URL组合。process.env.VUE_APP_BASE_URL
是从环境变量中获取的URL。在Vue项目中,以VUE_APP_
开头的环境变量可以在项目中访问,这些环境变量在.env
文件中设置。 -
timeout: 5000,
:timeout
选项指定了请求的超时时间,单位是毫秒。在这个例子中,超时时间被设置为5000毫秒(或5秒)。如果请求在5秒内没有完成,则将触发一个错误。
service.interceptors.response.use((response) => {
return response;
}, async (error) => {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
setTimeout(() => {
originalRequest._retry = true;
store.commit('SET_TOKEN', '');
storageService.set(storageService.USER_TOKEN, '');
store.commit('SET_USERINFO', '');
storageService.set(storageService.USER_INFO, '');
localStorage.removeItem('Partition');
window.location.reload();
}, 2000);
}
return Promise.reject(error);
});
export default service;
这段代码使用了axios
的拦截器功能,特别是针对响应进行拦截。拦截器允许你在请求或响应被then
或catch
处理之前拦截它们,并执行一些操作。让我们详细了解这段代码的工作方式:
-
service.interceptors.response.use((response) => { return response; }, async (error) => { ... });
: 这里定义了一个响应拦截器,用于在响应返回到调用代码之前执行某些操作。拦截器的第一个函数处理正常的响应,第二个函数处理错误响应。 -
return response;
: 对于正常的响应,拦截器什么也不做,只是返回响应。这意味着拦截器不会改变正常响应的行为。 -
const originalRequest = error.config;
: 从错误对象中提取原始请求的配置。这可以用于后续的重试逻辑或其他操作。 -
if (error.response.status === 401 && !originalRequest._retry) { ... }
: 这里检查响应的状态码是否为401,且原始请求未被重试(通过检查originalRequest._retry
标志)。HTTP状态码401通常表示未经授权,可能意味着用户的token已过期。 -
清除Token和用户信息: 如果检测到401错误,代码将设置一个2秒的延时,然后清除应用中的token和用户信息。它通过Vuex
store
来提交状态更改,同时使用storageService
来清除存储中的相应键。localStorage.removeItem('Partition')
也被用来清除本地存储中的一个特定项。 -
window.location.reload();
: 清除用户信息和token后,页面会被重新加载。这可能会导致用户被重定向到登录页面,或者应用以未登录状态重新启动。 -
return Promise.reject(error);
: 最后,错误被重新抛出,以便调用代码可以通过catch
来处理它。 -
export default service;
: 最后,service
实例被导出,以便其他文件和模块可以使用它。
这个拦截器的主要目的是处理token过期的情况。当检测到token过期(通过401状态码)时,它会清除所有相关的身份验证信息,并重新加载页面。
导入的三个包详解
import storageService from '@/service/storageService';
import axios from 'axios';
import store from '@/store';
axios
是一个流行的HTTP客户端库,用于从浏览器和Node.js发出HTTP请求。
store详见
storageService
对象主要提供了与浏览器的localStorage
交互的封装。在这个封装中,定义了一些基本操作来存储和读取数据。localStorage
用于将键值对存储在浏览器中,使其可以在页面重新加载之间持续存在。对于Token的操作,这个服务定义了常量用来标识Token的键名,并提供了基本的设置(set
)和获取(get
)方法来操作这个Token。
// 本地缓存服务
const PREFIX = 'sse_market';
// user 模块
const USER_PREFIX = `${PREFIX}user_`;
const USER_TOKEN = `${USER_PREFIX}token`;
const USER_INFO = `${USER_PREFIX}info`;
// 储存
const set = (key, data) => {
localStorage.setItem(key, data);
};
// 读取
const get = (key) => localStorage.getItem(key);
export default {
set,
get,
USER_TOKEN,
USER_INFO,
};
让我们详细看看这段代码:
-
定义前缀:
const PREFIX = 'sse_market';
: 定义了一个前缀,用于组织存储在localStorage
中的键。const USER_PREFIX =
${PREFIX}user_;
: 定义了用户模块的特定前缀,用于组织与用户相关的键。
-
定义用户相关的键:
const USER_TOKEN =
${USER_PREFIX}token;
: 定义了一个键来存储用户令牌。const USER_INFO =
${USER_PREFIX}info;
: 定义了一个键来存储用户信息。
-
存储方法:
const set = (key, data) => { localStorage.setItem(key, data); };
:set
方法用于将指定的键和数据存储在localStorage
中。
-
读取方法:
const get = (key) => localStorage.getItem(key);
:get
方法用于从localStorage
中获取指定键的数据。
-
导出对象: 这部分代码导出了一个对象,该对象包括了
set
和get
方法,以及之前定义的与用户相关的键。这样其他模块就可以使用这些方法和键来与localStorage
交互。