如何从Axios拦截器访问SvelteKit创建的Cookie?
我在登录页面的login/+page.server.js中编写了如下action:
export const actions = { default: async ({ request, cookies }) => { const data = Object.fromEntries(await request.formData()); // validate and create DTO. const loginData = loginDTO(data); // if errors returned from building the DTO (validation errors) then return the object. if (loginData?.errors && !emptyObject(loginData.errors)) { return { "data": loginData.data, "errors": loginData.errors, }; } // perform call to log in a user. const response = await login(loginData); // const response = await loginUser(loginData); if (response.success) { // save token to a cookie cookies.set( 'token', response.res.data.data, { path: '/', maxAge: 60 * 60 * 25 * 365, httpOnly: false, secure: false, } ) throw redirect(302, '/') } return { "data": loginData.data, "errors": response.errors, } } }
该逻辑会向后端发起用户认证请求,获取JWT token后通过SvelteKit的cookies对象成功设置Cookie,在Chrome开发者工具的应用面板中可查看到该Cookie。
现在我需要将Cookie值附加到Axios请求中,因此创建了如下拦截器:
import axios from "axios"; import Cookies from "js-cookie"; // let Cookies2 = Cookies.noConflict(); export const app = axios.create({ baseURL: "http://127.0.0.1:8080/api/v1", timeout: 1000, params: {}, // withCredentials: true, }) // Request interceptor. Whenever a new request goes out it will be caught // by the interceptor and whatever code is defined will be executed before continuing its flow. app.interceptors.request.use( config => { console.log("here in http middleware...") let token = Cookies.get() console.log("token: ", token); config.headers['Content-Type'] = 'application/json'; return config; }, error => { Promise.reject(error) } );
但遇到两个问题:
- 不知道如何在拦截器中导入并使用SvelteKit的
cookies对象; - 由于Cookie在客户端可见,我安装了
js-cookie来获取,但拦截器中的日志显示获取到的内容为空,无法读取Cookie。
请问这是什么原因?还有其他实现方式吗?另外,我也可以放弃Cookie方案改用Svelte Store,这两种方案的优缺点分别是什么?
一、Cookie读取失败的原因及解决方法
1. js-cookie读取为空的原因
你调用Cookies.get()时没指定Cookie名称,必须传入'token'才能拿到对应值,即Cookies.get('token')。另外检查Cookie的path是否和当前页面路径匹配——你设置的path: '/'是根路径,只要页面在域名下就没问题;如果是跨域场景,还要确认domain参数是否配置正确(本地127.0.0.1环境下大概率无需额外配置)。
2. 拦截器无法使用SvelteKit的cookies对象的原因
SvelteKit的cookies是服务器端专属上下文对象,仅在+page.server.js、+layout.server.js或API路由中可用,客户端代码(包括Axios拦截器)没有这个运行环境,无法直接导入使用。
二、可行的实现方式
方式1:修复js-cookie的使用
修改Axios拦截器代码,指定Cookie名称并将token放入请求头:
app.interceptors.request.use( config => { console.log("here in http middleware...") const token = Cookies.get('token'); // 传入目标Cookie名称 if (token) { config.headers['Authorization'] = `Bearer ${token}`; // 按后端要求格式放入请求头 } config.headers['Content-Type'] = 'application/json'; return config; }, error => Promise.reject(error) );
方式2:通过SvelteKit的load函数传递token到客户端
先在根布局的服务器端代码中读取Cookie,再传递给客户端页面:
// +layout.server.js export async function load({ cookies }) { const token = cookies.get('token'); return { token }; }
然后将token存入Svelte Store,在Axios拦截器中读取Store值:
// stores.js import { writable } from 'svelte/store'; export const tokenStore = writable(null);
// +layout.svelte <script> import { tokenStore } from '$lib/stores'; export let data; $tokenStore = data.token; </script>
// Axios拦截器 import { tokenStore } from '$lib/stores'; import { get } from 'svelte/store'; app.interceptors.request.use( config => { const token = get(tokenStore); if (token) { config.headers['Authorization'] = `Bearer ${token}`; } config.headers['Content-Type'] = 'application/json'; return config; }, error => Promise.reject(error) );
方式3:直接使用浏览器原生API读取Cookie
无需依赖第三方库,自己解析原生Cookie字符串:
function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); } // 拦截器中使用 const token = getCookie('token');
三、Cookie vs Svelte Store 优缺点对比
Cookie方案优点
- 自动持久化:Cookie会自动保存到浏览器,页面刷新、关闭重启后依然存在(在有效期内)
- 服务器端可读取:SvelteKit的服务器端代码(如
load函数、API路由)能直接读取Cookie,适合服务端渲染用户专属内容的场景 - 兼容性好:多数后端框架默认支持从Cookie或请求头读取JWT,符合HTTP认证规范
Cookie方案缺点
- 存储限制:单个Cookie最大4KB,总数量和大小受浏览器限制
- 跨域配置复杂:前后端域名不同时,需配置
SameSite、domain等参数,容易出问题 - 安全风险:当前设置
httpOnly: false,客户端可读取,存在XSS攻击风险;若设httpOnly: true,客户端又无法读取,只能通过服务端转发请求
Svelte Store方案优点
- 前端操作灵活:Store是前端内存状态,读写方便且支持响应式更新,适合组件间共享状态
- 无跨域问题:完全在前端内存中运行,无需考虑Cookie的跨域规则
- 存储限制宽松:只要浏览器内存足够,可存储更多数据(不建议存过大内容)
Svelte Store方案缺点
- 刷新丢失:默认Store是内存状态,页面刷新或关闭后会清空,需手动实现持久化(如存到
localStorage) - 服务器端无法直接读取:SvelteKit服务端代码不能访问客户端Store,需通过
load函数从Cookie或URL参数传递数据 - 安全风险:若存到
localStorage,依然可能被XSS攻击窃取,和httpOnly: false的Cookie风险类似
内容的提问来源于stack exchange,提问作者MrCujo

