You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SvelteKit客户端钩子不执行问题排查及路由保护方案咨询

SvelteKit客户端钩子不执行问题排查及路由保护方案咨询

我来帮你梳理下问题所在,再聊聊路由保护的方案选择:

一、客户端钩子不执行的原因及修复

1. 旧版通用hooks.ts已被弃用

你提到hooks.ts完全没被读取,这是因为新版SvelteKit已经把通用钩子拆分成了hooks.server.ts(服务端钩子)和hooks.client.ts(客户端钩子),原来的hooks.ts不再被框架识别。你需要把服务端相关逻辑移到hooks.server.ts,客户端逻辑留在hooks.client.ts。

2. 客户端钩子没有reroute这个方法

你写的reroute函数根本不是客户端钩子支持的钩子类型!目前SvelteKit客户端钩子只支持handle、handleError这几个方法,reroute要么是旧版本的API,要么是服务端钩子才有的逻辑。想要在客户端拦截路由并重定向,得用handle钩子,示例代码如下:

// src/hooks.client.ts
export async function handle({ event, resolve }) {
  console.log('Client handle hook triggered:', event.url);
  // 这里写你的路由判断逻辑
  if (event.url.pathname !== '/hello') {
    // 重定向到/hello
    return new Response(null, {
      status: 302,
      headers: { Location: '/hello' }
    });
  }
  // 正常处理请求
  return resolve(event);
}

替换成这个代码后,你应该能在浏览器控制台看到日志,并且路由会被重定向到/hello。

3. 模块加载但函数未执行的原因

你看到RUNNING: hooks.client.ts的日志,说明模块确实被加载了,但因为你导出的reroute不是客户端钩子的合法方法,所以框架根本不会调用它,换成handle就正常了。

二、路由保护:用钩子还是Layout?

你的疑问很合理,这两种方案各有适用场景,结合起来用效果最好:

1. 服务端钩子(推荐做权限验证)

既然你是对接Azure AD做认证,路由保护的核心逻辑一定要放在服务端钩子hooks.server.ts里。因为客户端代码可以被用户篡改,服务端验证才能确保真正的安全性——比如验证用户的Azure AD令牌是否有效、是否有权限访问当前路由。示例逻辑大概是这样:

// src/hooks.server.ts
export async function handle({ event, resolve }) {
  // 从session或请求头里获取Azure AD的用户信息/令牌
  const user = await event.locals.getSession();
  // 如果未登录且访问的是需要授权的路由
  if (!user && event.url.pathname.startsWith('/dashboard')) {
    return new Response(null, {
      status: 302,
      headers: { Location: '/login' }
    });
  }
  return resolve(event);
}

2. Layout组件(适合客户端UI处理)

Layout组件适合做客户端的友好提示,比如在未登录时显示登录按钮、隐藏页面内容,或者做客户端的路由跳转(但这只能作为补充,不能替代服务端验证)。比如在根+layout.svelte里:

<script>
  import { page } from '$app/stores';
  import { getSession } from '$lib/auth'; // 你的认证逻辑

  let user;
  async function checkAuth() {
    user = await getSession();
    if (!user && $page.url.pathname.startsWith('/dashboard')) {
      window.location.href = '/login';
    }
  }
  checkAuth();
</script>

{#if user}
  <nav>欢迎,{user.name}</nav>
{:else}
  <nav><a href="/login">登录</a></nav>
{/if}

<slot />

总结下:服务端钩子做安全拦截,Layout做用户体验优化,两者搭配是最佳实践。

备注:内容来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 08:00:28