Headless CMS如何与React集成时解决预渲染和API调用冲突?

佳佳的笔记 阅读 62

我在用Gatsby和Strapi搭建Headless CMS站点时遇到问题,页面预渲染时报401认证错误。虽然开发环境用wrapPageElement处理了JWT,但构建时静态生成还是会直接调用API原地址…

尝试在gatsby-node.js里这样改过:

exports.onPreInit = () => {
  process.env.API_URL = process.env.NODE_ENV === 'production' 
    ? 'https://api.example.com' 
    : 'http://localhost:1337';
};

但构建时依然提示”Unauthorized”,感觉生产环境没有正确带上Bearer token,应该怎样让预渲染阶段正常调用认证后的API?

我来解答 赞 2 收藏
二维码
手机扫码查看
2 条解答
利芹 ☘︎
生产环境预渲染需要在构建时就拿到token,不能依赖运行时环境变量。直接在gatsby-config.js里设置环境变量并注入headers:

require('dotenv').config()

module.exports = {
plugins: [
{
resolve: 'gatsby-source-strapi',
options: {
apiURL: process.env.STRAPI_API_URL,
token: process.env.STRAPI_TOKEN,
headers: {
Authorization: Bearer ${process.env.STRAPI_TOKEN}
}
}
}
]
}


记得在服务器上配置好STRAPI_TOKEN,本地和生产环境都能用。别忘了重启服务,环境变量要重新加载。
点赞 1
2026-02-17 15:14
迷人的海霞
我之前踩过这个坑,问题出在构建时API调用的认证方式上。Gatsby静态生成时没法直接用开发环境那种动态添加token的方式,因为这时候它其实是在无状态环境下跑的。

解决办法是把JWT写到 gatsby-config.js 里,通过环境变量注入:

require("dotenv").config({
path: .env.${process.env.NODE_ENV},
})

module.exports = {
siteMetadata: {
title: Your Site Title,
},
flags: { PRESERVE_WEBPACK_CACHE: true },
plugins: [],
}


然后在 .env.production 文件里设置你的生产环境API地址和token:


API_URL=https://api.example.com
AUTH_TOKEN=your_jwt_token_here


接下来修改你的API请求函数,确保构建时能带上认证头:

const fetchWithAuth = async (url, options = {}) => {
return fetch(process.env.API_URL + url, {
...options,
headers: {
...(options.headers || {}),
Authorization: Bearer ${process.env.AUTH_TOKEN},
},
})
}

exports.sourceNodes = async ({ actions, createContentDigest }) => {
const res = await fetchWithAuth('/content-types')
// 继续处理数据...
}


这样就能保证在预渲染阶段正确带上认证信息了。记得不要把敏感的token提交到代码库,.env文件要加到.gitignore里。
点赞 11
2026-02-01 07:02