一、token无感刷新
要实现 Token 无感刷新:
a. 请求时带上 Token
"每次发起 API 请求时,都需要在请求头中携带 Access Token,通常是使用 Authorization 字段进行传递:"
fetch('api/endpoint', {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
b. 检测 Token 过期
可以通过检查响应的状态码(如 401 Unauthorized)来判断 Access Token 是否过期。如果过期,就会向后端发送 Refresh Token 来获取新的 Access Token:
if (response.status === 401) {
await refreshToken(); // 如果 token 过期,刷新 token
return fetchData(url); // 刷新后重新发起请求
}
c. 刷新 Token 的流程
当 Access Token 过期时,我们会向后端发起请求,传递 Refresh Token 来请求新的 Access Token。若刷新成功,新的 Token 会存储在客户端,并继续用于后续请求。
const refreshToken = async () => {
const refreshToken = sessionStorage.getItem("refreshToken");
const response = await fetch("/refresh-token", {
method: "POST",
body: JSON.stringify({ refreshToken })
});
const { accessToken, newRefreshToken } = await response.json();
sessionStorage.setItem("accessToken", accessToken);
sessionStorage.setItem("refreshToken", newRefreshToken);
};
为了确保安全性,我们可以将 Refresh Token 存储在 HttpOnly cookie 中,这样就可以防止 XSS 攻击获取到 Refresh Token。同时,我们还可以使用 HTTPS 来加密数据传输,确保令牌在网络传输中的安全性。
二、require和import区别
Node.js 环境下的模块加载通常用 require,但 现代 JavaScript 使用 import 更为推荐,因为它支持静态分析和优化。
| 特性 | require (CommonJS) | import (ESM) |
|---|---|---|
| 模块系统 | CommonJS (CJS) | ES6 Module (ESM) |
| 引入语法 | const m = require('./m') | import { m } from './m' |
| 执行时机 | 运行时加载(同步执行代码) | 编译时加载(静态解析) |
| 值处理方式 | 值的拷贝(导出后原值变了,引入值不变) | 值的引用(Live Bindings,原值变了引入值也变) |
| 使用位置 | 可以在代码任何地方(如 if 块中) | 必须在顶部(除非使用 import()) |
| 支持环境 | Node.js 原生支持 | 现代浏览器 + Node.js (v12+) |
| 动态导入 | 本身即动态,但不支持 await import | 支持 import('./m').then(...) |
| 导出方式 | module.exports 或 exports | export 或 export default |
| 顶层变量 | 存在 __dirname, __filename | 不存在(需通过 import.meta.url 获取) |
this 指向 | 指向当前模块对象 | undefined |
三、object.keys的key和Object.values的value的顺序是?
1.整数索引:如果对象的属性名是 非负整数(例如 "0", "1", "2" 等),这些属性会按照从 小到大 的顺序排列。
const obj = { "1": "a", "3": "c", "2": "b" };
console.log(Object.keys(obj)); // ["1", "2", "3"]
2.字符串键:对于非整数的字符串键(例如 "name", "age" 等),它们会按 创建顺序 排列,也就是说,顺序就是你在对象中添加它们的顺序。
3.符号键 (Symbol) :符号类型的属性键会被 排在最后,并且仍然按创建顺序排列。
总结
- 整数键:按升序排列。
- 字符串键:按对象定义的顺序排列。
- 符号键:被排除在
Object.keys()之外,Object.getOwnPropertySymbols()可以获取符号键。