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

SvelteKit中Axios拦截器无法访问Cookie问题求助

问题描述

我在使用SvelteKit开发项目时遇到了Cookie相关问题,具体情况如下:

1. 服务端Cookie创建代码(路径:src\routes\api\auth\+server.js)

import {login} from "../../../api/auth.js";
import {loginDTO} from "../../../business/data-transfer-objects/login.js";
import {emptyObject} from "../../../helpers/index.js";
import {errorResponse, successResponse} from "../../../core/response.js";
import {AUTH_TOKEN_KEY} from "../../../core/consts.js";

/**
 * User Login -> if 200 returned from the server then save the returned token
 * into a cookie.
 * @param event
 * @returns {Promise<Response>}
 * @constructor
 */
export async function POST(event) {

    const data = await event.request.json();

    // 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 errorResponse(data, loginData.errors, 422)
    }

    // perform login.
    const response = await login(loginData);

    // if login is not successful then return error.
    if (response.status !== 200) {
        // remove password from data.
        delete data["password"];
        return errorResponse(data, response, response.status);
    }

    // if login is successful then set the auth cookie.
    event.cookies.set(AUTH_TOKEN_KEY, response.data.token, {
        // send cookie for every page
        path: '/',
        // server side only cookie so you can't use `document.cookie`
        httpOnly: false,
        // only requests from same site can send cookies
        sameSite: 'strict',
        // only sent over HTTPS in production
        secure: process.env.NODE_ENV === 'production',
        // set cookie to expire after a month
        maxAge: 60 * 60 * 24 * 30,
    })

    return successResponse(response.data, 200);
}

2. 登录表单调用接口的Actions代码

import { redirect } from "@sveltejs/kit";

/** @type {import('./$types').Actions} */
export const actions = {

    default: async ({request, fetch}) => {

        const data = Object.fromEntries(await request.formData());

        const res = await fetch('api/auth', {
            method: 'POST',
            headers: {
                'content-type': 'application/json'
            },
            body: JSON.stringify(data)
        });

        const response = await res.json()

        // todo CV-127: once dashboard page is implemented that's the place where this action shall be redirected to.
        if (response.status == 200) {
            throw redirect(302, '/')
        }

        return response;
    }
}

3. Cookie创建状态

Cookie已成功生成,详情如下:

championship-access-token   eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlYXQiOiIyMDIzLTA1LTIyVDAxOjI4OjMwLjk0MzAwMTE3MloiLCJpYXQiOjE2ODQ3MTY5MTAsImlkIjo3fQ.VaVfzgnib0DhzRO8jUJ-X_2BRIiAGXIq8eEQOs85anI localhost   /   6/20/2023, 8:55:10 PM   192 B       ✓   Strict

Cookie截图

4. 前端Axios拦截器问题

使用js-cookie库无法获取目标Cookie,也无法创建新Cookie,拦截器代码:

import axios from "axios";
import Cookies from 'js-cookie';

export const app = axios.create({
    baseURL: "http://127.0.0.1:8080/api/v1",
    timeout: 1000,
    params: {},
});

app.interceptors.request.use(
    config => {
        console.log("interceptor -> retrieving cookie:");
        Cookies.set("test123", "asdasdasd")
        console.log(Cookies.get(AUTH_TOKEN_KEY));
        console.log("test cookie: ", Cookies.get("test123"))
        console.log("cookie: ", Cookies.get(AUTH_TOKEN_KEY));
        console.log("ALL COOKIES", Cookies.get())
        config.headers['Content-Type'] = 'application/json';
        return config;
    },
    error => {
        Promise.reject(error)
    }
);

核心问题

  • 明明设置了httpOnly: false,但Cookie仍被标记为HttpOnly
  • 前端无法通过js-cookie访问或创建Cookie

问题分析与解决方案

一、Cookie被标记为HttpOnly的原因及修复

你设置的httpOnly: false未生效,主要有两个可能:

  1. 后续操作覆盖了Cookie配置:重定向操作或自定义的successResponse函数可能重新设置了同名Cookie,覆盖了httpOnly属性。
  2. SvelteKit内置Cookie工具的默认行为干扰:部分场景下event.cookies.set的配置会被框架默认值覆盖。

修复方法:
直接手动设置响应头,绕过SvelteKit的Cookie工具,确保配置完全生效:

// 替换原来的event.cookies.set代码
const cookieValue = `${AUTH_TOKEN_KEY}=${response.data.token}; Path=/; HttpOnly=false; SameSite=Strict; Max-Age=${60 * 60 * 24 * 30}`;
if (process.env.NODE_ENV === 'production') {
  event.response.headers.append('Set-Cookie', `${cookieValue}; Secure`);
} else {
  event.response.headers.append('Set-Cookie', cookieValue);
}

同时检查successResponse函数,确保它没有额外设置同名Cookie。

二、前端无法访问Cookie的原因及修复

前端拿不到Cookie和第一个问题直接相关,还可能受跨域限制影响:

  1. HttpOnly属性限制:如果Cookie是HttpOnly状态,前端JS(包括js-cookie)完全无法读取,必须先解决第一步的HttpOnly问题。
  2. 跨域请求限制:你的Axios请求地址是http://127.0.0.1:8080,而SvelteKit通常运行在localhost:5173,端口不同属于跨域,会限制Cookie的传递和访问。

修复方法:

1. 确认Cookie的HttpOnly状态

在浏览器开发者工具的Application -> Cookies面板中,查看目标Cookie的HttpOnly选项是否未被勾选。如果仍勾选,回到第一步排查服务端设置。

2. 处理跨域问题

方案A:使用SvelteKit代理请求(推荐)

将Axios的请求地址改为相对路径,通过Vite代理转发到后端,避免跨域:

  • 修改Axios配置:
    export const app = axios.create({
        baseURL: "/api/v1", // 改为相对路径
        timeout: 1000,
        params: {},
    });
    
  • 在vite.config.js中添加代理配置:
    import { sveltekit } from '@sveltejs/kit/vite';
    import { defineConfig } from 'vite';
    
    export default defineConfig({
        plugins: [sveltekit()],
        server: {
            proxy: {
                '/api/v1': {
                    target: 'http://127.0.0.1:8080',
                    changeOrigin: true
                }
            }
        }
    });
    

方案B:跨域携带Cookie

如果必须直接请求跨域地址,需要同时修改前端和后端配置:

  • 前端Axios开启携带凭证:
    export const app = axios.create({
        baseURL: "http://127.0.0.1:8080/api/v1",
        timeout: 1000,
        params: {},
        withCredentials: true // 开启该配置
    });
    
  • 后端配置CORS:设置响应头Access-Control-Allow-Credentials: true,且Access-Control-Allow-Origin必须指定你的前端具体地址(不能用*)。

3. 验证js-cookie的使用

确保AUTH_TOKEN_KEY的值和Cookie的名称完全一致(比如championship-access-token),Cookie名称区分大小写。

三、快速验证步骤

  1. 在浏览器控制台输入document.cookie,如果能看到目标Cookie,说明HttpOnly设置正确;如果看不到,继续排查服务端配置。
  2. 检查Application面板的Cookie列表,确认HttpOnly选项的状态。

内容的提问来源于stack exchange,提问作者MrCujo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:37:37