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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:48:02