核心思路是将权限检查封装为Promise,在路由守卫(Vue Router beforeEach)或loader(React Router v6+)中等待其完成再决定放行或重定向;需避免重复请求、区分错误类型并服务端兜底。

在 JavaScript 单页应用(SPA)中,路由加载前做权限异步验证,核心思路是:**把权限检查封装成 Promise,在路由跳转的守卫(如 Vue Router 的 beforeEach 或 React Router v6 的 loader)中等待它完成,再决定是否放行或重定向。**
Vue Router 中使用 beforeEach + Promise 验证
Vue Router 3/4 都支持异步守卫。只要守卫函数返回 Promise(或直接是 async 函数),Router 就会等待其 resolve/reject 后再继续导航。
- 权限校验逻辑(如调用 API 检查用户角色)必须返回 Promise
- 验证通过:调用
next()放行;失败:调用next('/login')或抛出错误触发全局错误处理 - 避免在守卫里重复请求 —— 可配合缓存(如 pinia/vuex 存储权限状态)或添加 loading 状态防多次触发
示例:
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
router.beforeEach(async (to, from, next) => {
// 跳转目标路由需要权限
if (to.meta.requiresAuth) {
try {
// 调用异步权限接口(返回 Promise)
const hasPermission = await checkUserPermission(to.meta.permissionKey);
if (hasPermission) {
next(); // ✅ 允许进入
} else {
next('/403'); // ❌ 拒绝访问
}
} catch (err) {
next('/login?redirect=' + to.fullPath); // ⚠️ 登录态失效或网络异常
}
} else {
next(); // 不需要权限,直接放行
}
});
React Router v6.4+ 使用 loader 实现预加载验证
v6.4 引入了 loader 函数,它会在路由组件渲染前执行,并天然支持 Promise(包括 async/await)。验证失败时可抛出 Response(如 403)或自定义错误,由 ErrorBoundary 或 useRouteError 处理。
立即学习“Java免费学习笔记(深入)”;
-
loader必须导出为对象字段,不能写在组件内 - 推荐将权限逻辑抽离为独立函数(返回 Promise),便于复用和测试
- 若需跳转(如未登录重定向),不能直接调用
useNavigate—— loader 是纯函数,应抛出redirect()(来自react-router-dom)
示例:
import { redirect } from 'react-router-dom';
<p>export async function permissionLoader({ params }) {
const requiredPerm = 'user:edit';</p><p>try {
const auth = await getCurrentAuth(); // 返回 Promise
if (!auth.isAuthenticated) throw new Response('', { status: 401 });
if (!auth.permissions.includes(requiredPerm)) throw new Response('', { status: 403 });</p><pre class="brush:php;toolbar:false;">return { user: auth.user }; // 传给组件的 loader 数据
} catch (err) { if (err.status === 401) { throw redirect('/login?from=' + window.location.pathname); } if (err.status === 403) { throw redirect('/403'); } throw err; } }
// 路由定义
{
path: '/profile/edit',
element:
通用建议:提升体验与健壮性
- 加 Loading 状态:在验证期间显示骨架屏或加载指示器,避免白屏或误操作
- 缓存权限结果:避免每次跳转都发请求,可用内存缓存(如 Map)或结合 token 过期时间自动刷新
- 区分错误类型:网络失败、token 过期、权限不足应有不同响应(重试、跳登录、展示提示)
- 服务端兜底:前端验证仅作体验优化,关键接口仍需后端鉴权,防止绕过
不推荐的做法
- 在组件
useEffect中做权限判断并跳转 —— 路由已进入,可能造成闪屏或状态残留 - 用同步方式模拟异步(如 localStorage 查权限)—— 无法应对动态权限变更
- 把整个路由配置写死在 Promise.then 里 —— 破坏路由声明式结构,难以维护


















