SvelteKit load方法带授权头请求时SSR无法获取Cookie如何解决
核心问题点
externalFetch钩子接收到的request参数是服务端构造的出站请求对象,并非用户浏览器发来的原始入站请求,直接从该对象读取Cookie必然为空,无法获取浏览器携带的jwt字段。- 原有代码存在变量引用错误:解析Cookie时赋值的变量名为
token,拼接授权头时错误使用了未定义的jwt变量,即使拿到Cookie也会触发运行时报错。 - 触发
externalFetch钩子的前提是:load函数内必须使用SvelteKit注入的fetch方法发起请求,直接调用全局原生fetch不会走该钩子逻辑。
正确实现方案
第一步:通过handle钩子传递原始请求的Cookie
externalFetch本身无法直接获取用户入站请求的上下文,需要先通过handle钩子解析原始请求的Cookie,将jwt存入event.locals供后续钩子调用。注意钩子逻辑仅运行在服务端,代码需要写在hooks.server.ts文件中:
import type { Handle, ExternalFetch } from '@sveltejs/kit'; import { parse } from 'cookie'; // 提前安装cookie依赖:npm i cookie export const handle: Handle = async ({ event, resolve }) => { const cookieHeader = event.request.headers.get('cookie') || ''; const parsedCookies = parse(cookieHeader); // 将解析到的jwt存入locals,整个服务端请求生命周期内都可访问 event.locals.jwt = parsedCookies.jwt; return resolve(event); }; export const externalFetch: ExternalFetch = async ({ request, fetch, event }) => { const token = event.locals.jwt; if (token) { // 克隆原始请求,避免修改不可变的Request对象,合并原有请求头和授权头 const authenticatedRequest = new Request(request, { headers: new Headers({ ...Object.fromEntries(request.headers), 'Authorization': `Bearer ${token}` }) }); return fetch(authenticatedRequest); } // 无token时直接发起原始请求 return fetch(request); };
第二步:load函数使用规范
在路由对应的+page.ts/+layout.ts(即原语法中context="module"的脚本块)中,必须使用load入参提供的fetch方法发起数据请求,不要引入全局原生fetch:
/** @type {import('./$types').PageLoad} */ export async function load({ fetch }) { // 此处使用框架注入的fetch,SSR阶段会自动经过externalFetch钩子处理 const response = await fetch('/api/your-target-endpoint'); return { list: await response.json() }; }
额外优化提示
如果请求的是同域接口,不需要手动实现externalFetch追加授权头:SvelteKit提供的load方法内置的fetch,在SSR模式下会自动透传当前用户请求的Cookie头到同域接口,仅当调用跨域外部接口、需要把Cookie转换为Authorization头发起认证时,才需要使用上述钩子方案。
内容的提问来源于stack exchange,提问作者Cola Motorolla
相关产品推荐
相关产品推荐

