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

如何从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)
    }
);

但遇到两个问题:

  1. 不知道如何在拦截器中导入并使用SvelteKit的cookies对象;
  2. 由于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:00:42