面试题答案
一键面试可能出现的问题及原因
- 重定向闪烁:
- 原因:在SSR阶段,服务器根据路由守卫规则判断用户权限,若权限不足则返回登录页面的HTML。但在客户端接管后,客户端代码可能再次进行权限检查,又一次触发重定向,导致页面先显示了服务器返回的登录页面,然后客户端又重定向一次,出现闪烁现象。这是因为SSR和CSR环境下权限检查时机和状态同步不一致。
- 数据不一致:
- 原因:在SSR时,权限判断依据的可能是服务器端的会话状态等信息。而在CSR时,可能依赖于客户端存储(如localStorage、sessionStorage)的信息来判断权限。如果服务器端和客户端的数据没有正确同步,比如服务器端会话过期但客户端存储未更新,就会导致权限判断不一致。
优化方案
- 解决重定向闪烁:
- 方案:在服务器端返回HTML时,通过在HTML的元数据(如
<meta>
标签)或自定义的data属性中,携带权限验证结果。客户端代码在初始化时,读取这些信息,若已经有明确的权限验证结果(如权限不足已重定向到登录页面),则不再重复进行权限检查和重定向。例如,在服务器端渲染的页面中添加:
客户端代码在初始化时:<html> <head> <meta name="permission-result" content="denied" /> </head> <body> <!-- 页面内容 --> </body> </html>
const permissionResult = document.querySelector('meta[name="permission - result"]').content; if (permissionResult === 'denied') { // 不再进行重定向,因为服务器已处理 } else { // 正常进行权限检查 }
- 方案:在服务器端返回HTML时,通过在HTML的元数据(如
- 解决数据不一致:
- 方案:在服务器端和客户端之间建立统一的状态管理机制。可以使用JWT(JSON Web Tokens),服务器在生成JWT时,将用户权限等必要信息包含在内。客户端在每次请求时,将JWT发送到服务器,服务器通过验证JWT来确认用户权限。同时,客户端在本地存储JWT,在CSR时依据JWT中的权限信息进行权限判断。这样保证了SSR和CSR模式下权限判断依据的数据一致性。
确保SSR和CSR模式下路由守卫的一致性和稳定性
- 统一权限检查逻辑:将权限检查的核心逻辑封装成独立的函数或模块,在SSR和CSR场景下共同引用。这样无论在服务器端还是客户端进行权限判断,使用的都是相同的逻辑。例如:
在服务器端路由守卫和客户端路由守卫中都引用该函数:// permission.js export function checkPermission(user) { // 权限检查逻辑,如检查用户角色等 return user.role === 'admin'; }
// server - side route guard import { checkPermission } from './permission.js'; export function serverSideRouteGuard(event) { const user = event.locals.user; if (!checkPermission(user)) { // 重定向到登录页面 } }
// client - side route guard import { checkPermission } from './permission.js'; export function clientSideRouteGuard() { const user = getCurrentUser(); if (!checkPermission(user)) { // 重定向到登录页面 } }
- 状态同步:如前面提到的,使用JWT等技术保证服务器端和客户端的状态同步。同时,可以在客户端设置一个机制,定期向服务器端验证权限状态,确保本地存储的权限信息与服务器端保持一致。例如,每隔一段时间(如5分钟)发送一个请求到服务器验证JWT的有效性,并更新本地状态。
- 测试:编写集成测试和端到端测试,模拟SSR和CSR两种场景下的权限管理流程。测试在不同权限状态下,页面的重定向、权限检查是否正确,确保一致性和稳定性。可以使用测试框架如Cypress来进行端到端测试,测试在不同权限下的路由导航等功能。