SvelteKit如何实现外部API返回401错误的全局处理?
全局处理外部API返回401错误的方案
核心思路是同时覆盖SSR阶段请求和客户端阶段请求两个场景的401逻辑,通过统一请求封装+钩子拦截的方式实现需求:
1. 封装全局统一的请求工具
首先废弃零散的裸调用fetch逻辑,统一使用封装的请求函数,把JWT注入、401判断逻辑统一收敛在这个函数里:
// src/lib/api.js export async function apiFetch(jwt, url, options = {}) { const mergedOptions = { ...options, headers: { ...options.headers, Authorization: jwt ? `Bearer ${jwt}` : '' } } const res = await fetch(url, mergedOptions) if (res.status === 401) { // 区分运行环境做不同处理 if (typeof window === 'undefined') { // SSR阶段抛出标识错误,后续交给hooks捕获处理 throw new Error('UNAUTHORIZED') } else { // 客户端阶段直接执行清权+跳转逻辑 document.cookie = 'jwt=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 UTC;' import('$app/stores').then(({ session }) => { session.update(val => ({ ...val, jwt: null })) }) import('$app/navigation').then(({ goto }) => { goto('/login') }) } } return res }
后续所有页面/接口的API请求都调用这个apiFetch函数传入JWT即可。
2. 处理SSR阶段的401错误
修改hooks.js的handle函数,捕获SSR阶段抛出的认证错误,直接在服务端完成清Cookie和重定向操作:
// hooks.js export async function handle({ request, resolve }) { request.locals.jwt = request.cookies.jwt try { return await resolve(request) } catch (err) { if (err.message === 'UNAUTHORIZED') { // 服务端直接设置清空Cookie的响应头,同时重定向到登录页 return { status: 302, headers: { 'set-cookie': 'jwt=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 UTC;', 'location': '/login' } } } // 其他错误正常抛出 throw err } } export function getSession(request) { return { jwt: request.locals.jwt } }
3. 补充兜底逻辑
如果存在部分未使用封装请求的场景,可以在根__error.svelte中补充客户端侧的401兜底判断:
<!-- src/routes/__error.svelte --> <script> import { browser } from '$app/env' import { goto } from '$app/navigation' import { session } from '$app/stores' export let status if (browser && status === 401) { document.cookie = 'jwt=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 UTC;' session.update(val => ({ ...val, jwt: null })) goto('/login') } </script> <!-- 其他错误页展示逻辑 -->
内容的提问来源于stack exchange,提问作者Kevin Renskers
相关产品推荐
相关产品推荐

