给我一个在sessionStorage存储状态的方法,例如在sessionStorage存一个status:true,,然后再给我一个从sessionStorage中删除status的方法
时间: 2024-03-14 09:41:29 浏览: 53
在JavaScript中,可以使用sessionStorage对象来在浏览器的会话期间存储数据。下面是一个示例,展示如何在sessionStorage中存储状态并删除状态:
1. 存储状态到sessionStorage中:
```javascript
sessionStorage.setItem('status', 'true');
```
这将在sessionStorage中创建一个名为"status"的键,并将其值设置为"true"。
2. 从sessionStorage中删除状态:
```javascript
sessionStorage.removeItem('status');
```
这将从sessionStorage中删除名为"status"的键及其对应的值。
请注意,sessionStorage中存储的数据仅在当前会话期间有效,当用户关闭浏览器标签或窗口时,数据将被清除。
相关问题
</head> <body> <el-form id="login" class="demo-ruleForm" :rules="rules" :model="ruleForm"> <el-form-item label="用户名" prop="username"> <el-input v-model="ruleForm.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input v-model="ruleForm.password" type="password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="loginHandler()">登录</el-button> </el-form-item> </el-form> </body> <script> new Vue({ el: "#login", data() { return { ruleForm:{ username: "", password: "", }, rules: { username: [{ required: true, message: '请输入用户名', trigger: 'blur' }, { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' } ], password: [{ required: true, message: '请输入密码', trigger: 'blur' }, { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' } ] } } }, methods: { loginHandler() { axios.post("http://localhost:9000/mvc_web/login?username="+this.ruleForm.username + "&password=" + this.ruleForm.password).then(function(response) { if(response.status==200){ if(response.data.id!=0){ //将数据保存在本地缓存中 /* window.localStorage.setItem("user",JSON.stringify(response.data)) */ //将数据保存到服务器中 sessionStorage.setItem("user",JSON.stringify(response.data)) window.location.href="home.html"} else{ console.log("账户或密码错误,请重新输入") } } }) .catch(function(error) { console.log(error) }) } } }) </script> </html> //Home.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="js/vue.js"></script> </head> <body> <div id="home"> 欢迎{{user.username}}登录 </div> </body> <script> new Vue({ el:"#home", data:{ user:JSON.parse(sessionStorage.getItem("user")) } }) </script> </html>解释每行代码
这段代码是一个基于Vue.js的前端页面,主要包含两个部分:一个是登录页面,另一个是主页。
在登录页面部分,代码中的el-form组件是一个表单组件,包含用户名和密码两个输入框以及登录按钮。其中,v-model指令用于实现数据的双向绑定,rules属性用于设置表单验证规则。loginHandler方法是登录按钮的点击事件处理函数,通过Axios库向服务器发送POST请求,将用户名和密码作为参数传递给后台,如果登录成功则将用户信息保存在sessionStorage中,跳转到主页;否则在控制台输出错误信息。
在主页部分,代码中的div元素用于展示欢迎信息,通过Vue.js实现数据的双向绑定,显示当前登录用户的用户名。其中,JSON.parse方法用于将sessionStorage中保存的JSON字符串转换为JavaScript对象,从而实现数据的获取和展示。
在axios请求中使用TypeScript实现双token的逻辑,当token过期时中断请求,使用refreshToken获取token,获取token成功后,将token和refreshToken存储在本地,重新发送之前中断的请求。在下面代码中加入双token的逻辑。 import type { CustomAbortController, UseRequestWrapperConfig, UseRequestWrapperExecConfig, } from './types.ts' import useGlobalLoadingStore from '@/store/useGlobalLoadingStore.ts' import { onTokenExpired } from '@/utils/business.ts' import { AxiosError, CanceledError } from 'axios' import { onMounted, onUnmounted, ref } from 'vue' import { ResponseError } from './_base.ts' function useRequestWrapper<T>(wrapperConfig: UseRequestWrapperConfig<T>) { const globalLoadingStore = useGlobalLoadingStore() const { requestFn, onError, onSuccess } = wrapperConfig /** * is interrupt prev request */ let interruptPrevRequest = false /** * is use global loading */ let globalLoading = false /** * is show overlay when global loading */ let globalLoadingOverlay = false /** * loading */ const isLoading = ref(false) function openLoading() { isLoading.value = true globalLoading && globalLoadingStore.openGlobalLoading(globalLoadingOverlay) } function closeLoading() { isLoading.value = false globalLoading && globalLoadingStore.closeGlobalLoading(globalLoadingOverlay) } /** * is error happen */ const isError = ref(false) const data = ref<T>() function setData(next?: T) { data.value = next } /** * abort request controller */ const abortController: CustomAbortController = { _value: new AbortController(), get value() { if (this._value && !this._value.signal.aborted) { return this._value } else { this._value = new AbortController() return this._value } }, abort() { abortController.value.abort() }, } /** * request execute * @param execConfig request execute config */ async function exec(execConfig?: UseRequestWrapperExecConfig) { if ( (wrapperConfig.authCh
<think>嗯,用户想在现有的Axios TypeScript封装中添加双token处理逻辑。让我先理清楚需求。双token机制通常涉及访问令牌和刷新令牌,当访问令牌过期时,用刷新令牌获取新的访问令牌,然后重试原来的请求。这需要处理请求拦截、响应拦截、错误重试,还有本地存储的管理。
首先,用户提到现有的Axios封装,可能需要检查当前的请求和响应拦截器是否已经存在。比如,现有的拦截器可能已经处理了token的添加,但可能没有处理过期的情况。根据用户提供的引用[1],他们已经在请求头中添加了token,但需要在过期时自动刷新。
接下来,需要确定如何检测token过期。通常,API在token过期时会返回401状态码。因此,在响应拦截器中,如果检测到401,就应该触发刷新token的逻辑。但要注意,如果刷新token的请求也返回401,可能需要跳转到登录页面。
然后是刷新token的过程。当检测到access token过期,应该使用refresh token调用刷新接口,获取新的access token和可能的新的refresh token。这里需要确保在刷新过程中,其他请求被暂停,直到新的token获取成功,否则可能会有多个并发的刷新请求,导致问题。因此,需要引入一个队列来存储等待的请求,或者使用一个标志位来标记是否正在刷新。
另外,需要考虑并发请求的情况。例如,多个请求同时检测到token过期,应该只触发一次刷新token的请求,其他请求等待刷新完成后再用新的token重试。这就需要使用一个isRefreshing变量和一个队列来管理待处理的请求。
还有本地存储的问题,用户提到保存到sessionStorage或者localStorage。根据引用[1],他们使用的是sessionStorage,所以刷新后需要更新存储中的token。同时,引用[2]提到页面刷新导致store数据丢失,可能需要将token持久化存储,或者在初始化时从存储中读取。
在代码结构上,需要在Axios实例中添加请求拦截器来携带access token,响应拦截器处理401错误,并触发刷新流程。刷新token成功后,需要更新Axios的默认请求头,并重试原来的请求。此外,还要处理刷新token失败的情况,比如跳转到登录页面。
还需要注意TypeScript的类型定义,比如在拦截器中正确声明错误类型,避免类型错误。引用[4]提到了TypeScript的post请求,可能需要参考相关的类型定义。
最后,测试不同场景,如token过期时的单个请求、多个并发请求、刷新token失败等情况,确保逻辑正确。比如,在刷新token期间,新的请求应该被加入队列,等待新的token;刷新成功后,所有队列中的请求用新token重试;如果刷新失败,则清除本地存储并跳转登录。
总结步骤:
1. 在请求拦截器中添加access token。
2. 在响应拦截器中检测401错误。
3. 当检测到401时,使用refresh token获取新的access token。
4. 在刷新过程中,暂停其他请求,将其加入队列。
5. 刷新成功后,用新token重试队列中的请求。
6. 处理刷新失败的情况,如跳转到登录页。</think>以下是在Axios TypeScript中实现双token机制的完整方案:
### 一、核心实现步骤
1. **定义Token存储接口**
```typescript
interface TokenPair {
accessToken: string;
refreshToken: string;
}
```
2. **创建Axios实例**
```typescript
const service = axios.create({
timeout: 10000,
headers: { 'Content-Type': 'application/json' }
});
```
3. **请求拦截器(携带accessToken)**
```typescript
service.interceptors.request.use(config => {
const accessToken = sessionStorage.getItem('accessToken');
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
});
```
4. **响应拦截器(处理401错误)**
```typescript
let isRefreshing = false;
let requestsQueue: ((token: string) => void)[] = [];
service.interceptors.response.use(
response => response,
async error => {
if (error.response?.status === 401 && !error.config._retry) {
error.config._retry = true;
if (!isRefreshing) {
isRefreshing = true;
try {
const newTokens = await refreshToken();
sessionStorage.setItem('accessToken', newTokens.accessToken);
sessionStorage.setItem('refreshToken', newTokens.refreshToken);
requestsQueue.forEach(cb => cb(newTokens.accessToken));
requestsQueue = [];
return service(error.config);
} catch (refreshError) {
sessionStorage.clear();
window.location.href = '/login';
return Promise.reject(refreshError);
} finally {
isRefreshing = false;
}
}
return new Promise(resolve => {
requestsQueue.push(token => {
error.config.headers.Authorization = `Bearer ${token}`;
resolve(service(error.config));
});
});
}
return Promise.reject(error);
}
);
```
5. **Token刷新函数**
```typescript
async function refreshToken(): Promise<TokenPair> {
const refreshToken = sessionStorage.getItem('refreshToken');
const { data } = await axios.post<TokenPair>('/auth/refresh', { refreshToken });
return data;
}
```
### 二、关键机制说明
1. **并发请求处理**:当多个请求同时触发401时,只会发送一个刷新请求,后续请求进入等待队列[^3]
2. **本地存储同步**:成功刷新后自动更新sessionStorage中的token,保持前后端状态一致[^1][^2]
3. **失败处理**:刷新失败时清空存储并跳转登录页,避免无效token循环[^4]
### 三、补充优化建议
1. 建议在本地存储加密敏感数据
2. 可添加刷新token的过期时间检查
3. 推荐使用Vuex/Pinia进行状态管理,避免直接操作sessionStorage[^2]
阅读全文
相关推荐















