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

在getStaticProps中调用Next.js /api接口无法设置Cookie

问题原因与解决方案

问题根源

  • getStaticProps的执行环境:它是在构建阶段(或增量静态再生时)在Next.js服务器端运行的,完全脱离用户的浏览器环境。你在getStaticProps里调用fetch('http://localhost:3000/api/...')本质是服务器内部的请求,和用户浏览器没有关联。
  • Cookie无法设置的原因:/api接口返回的Set-Cookie头只会被发起请求的Next.js服务器接收,不会传递到用户的浏览器中,自然无法在客户端存储Cookie。
  • 重复获取token的原因:因为用户浏览器里根本没有保存Cookie,后续任何需要验证Cookie的逻辑都会判定“无有效token”,进而重复调用远程API。

解决方案

根据你的业务需求选择以下方案:

方案1:改用getServerSideProps(推荐,适合需服务器端处理用户状态的场景)

放弃静态生成,改用getServerSideProps——它会在每次用户请求页面时在服务器端执行,此时可以直接操作用户的请求/响应对象,处理Cookie逻辑:

修改/cookietest.js:

import cookie from 'cookie'
import Head from 'next/head'
import Header from '../components/Header' // 假设Header组件路径正确

function cookietest({tokenObj}) {
    const pageTitle = 'cookie test'
    return (
        <div>
            <Head>
                <title>Cookie tester</title>
            </Head>
            <Header pageTitle={pageTitle} />
            <p>{tokenObj.token}</p>
            <p>{tokenObj.message}</p>
        </div>
    )
}

export const getServerSideProps = async (context) => {
    const { req, res } = context
    // 解析用户请求中的Cookie
    const cookies = cookie.parse(req.headers.cookie || '')
    let tokenObj

    if (cookies.token) {
        // 这里可添加token有效性验证逻辑
        tokenObj = {
            token: cookies.token,
            message: '使用已有的Cookie token'
        }
    } else {
        // 调用远程API获取真实token
        const remoteToken = '从远程API返回的有效token'
        // 设置Cookie到用户浏览器
        res.setHeader("Set-Cookie", cookie.serialize("token", remoteToken, {
            httpOnly: true,
            secure: process.env.NODE_ENV === 'production', // 生产环境才启用secure
            maxAge: 60 * 60,
            sameSite: "strict",
            path: "/"
        }))
        tokenObj = {
            token: remoteToken,
            message: '获取新token并设置Cookie'
        }
    }

    return {
        props: { tokenObj }
    }
}

export default cookietest

这种方式无需额外的/api接口,直接在服务器端完成Cookie验证和设置,逻辑更简洁,也能确保Cookie正确发送给用户浏览器。

方案2:保留getStaticProps,将token逻辑移到客户端

如果必须使用静态生成(比如页面内容无需用户个性化、追求极致性能),则把获取token的逻辑移到客户端组件中:

修改/cookietest.js:

import { useState, useEffect } from 'react'
import Head from 'next/head'
import Header from '../components/Header' // 假设Header组件路径正确

function cookietest() {
    const pageTitle = 'cookie test'
    const [tokenObj, setTokenObj] = useState(null)

    useEffect(() => {
        async function getToken() {
            const res = await fetch('/api/otherpath/token')
            const data = await res.json()
            setTokenObj(data)
        }
        getToken()
    }, [])

    if (!tokenObj) {
        return <div>加载中...</div>
    }

    return (
        <div>
            <Head>
                <title>Cookie tester</title>
            </Head>
            <Header pageTitle={pageTitle} />
            <p>{tokenObj.token}</p>
            <p>{tokenObj.message}</p>
        </div>
    )
}

export default cookietest

此时请求是从用户浏览器发往/api接口,Set-Cookie头会被浏览器正确处理,后续请求也能带上Cookie。但页面初始加载时会有空白/加载状态,需要额外处理。

额外注意点

  • 测试环境下,secure: true会导致浏览器拒绝保存Cookie(因为localhost是HTTP协议),建议根据环境动态设置:secure: process.env.NODE_ENV === 'production'。
  • 若坚持使用本地/api接口,必须确保请求是从客户端发起,而非服务器端的getStaticProps内部。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:05:59