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

MERN栈React前端Cookie浏览器不保存但Postman可用问题求助

跨域场景下浏览器无法保存后端Cookie的问题排查

我使用React搭配RTK-Query对接基于Node、Express、Nginx部署的后端API时遇到棘手问题:通过Postman调用API一切正常(登录、修改数据等操作,只要不删除Postman中的Token Cookie就能正常执行),但浏览器始终无法保存后端返回的Cookie。

此前前后端部署在同一台EC2服务器时完全正常,现在按最佳实践拆分架构——前端部署在S3+CloudFront、后端单独部署在EC2后,出现两种异常情况:

  • 本地运行React应用登录时,浏览器返回200状态码且响应体内容正确,服务器也确实返回了带JWT的Cookie,但浏览器的Web存储中找不到该Cookie。
  • 前端部署到S3+CloudFront后,登录请求无状态码,仅提示混合内容阻止(mixed block)。

环境配置详情

Nginx配置

Nginx配置

Node Server代码

import "express-async-errors";
import express from "express";
import cookieParser from "cookie-parser";

const app = express();
import dotenv from "dotenv";
dotenv.config();

import { dirname } from "path";
import { fileURLToPath } from "url";
import path from "path";

import helmet from "helmet";
import xss from "xss-clean";
import mongoSanitaze from "express-mongo-sanitize";
import rateLimit from "express-rate-limit";
import cors from "cors";

// 限流配置
const limiter = rateLimit({
  windowMs: 10 * 60 * 1000, // 10分钟
  max: 200, // 限制每个IP在窗口期内最多200次请求
  standardHeaders: true, // 在响应头返回限流信息
  legacyHeaders: false, // 禁用旧版限流响应头
  message: "该IP请求过于频繁,请10分钟后重试",
});

// 数据库连接与用户认证
import connectDB from "./db/connect.js";

// 路由
import authRouter from "./routes/authRoutes.js";
import taskRouter from "./routes/tasksRoutes.js";
import diaryRouter from "./routes/diaryRoutes.js";

// 中间件
import notFoundMiddleware from "./middleware/notFound.js";
import errorHandlerMiddleware from "./middleware/errorHandler.js";
import morgan from "morgan";
import authenticateUser from "./middleware/auth.js";

// 开发环境启用morgan日志
if (process.env.NODE_ENV !== "production") {
  app.use(morgan("dev"));
}

app.use(cors());
app.use(express.json());
app.use(helmet());
app.use(xss());
app.use(mongoSanitaze());
app.use(limiter);

app.use(cookieParser());

app.use("/api/v1/auth", authRouter);
app.use("/api/v1/tasks", authenticateUser, taskRouter);
app.use("/api/v1/diary", authenticateUser, diaryRouter);

app.use(notFoundMiddleware);
app.use(errorHandlerMiddleware);

const port = process.env.PORT || 7000;

const start = async () => {
  try {
    await connectDB(process.env.MONGO_URL);
    app.listen(port, () => {
      console.log(`服务器已启动,监听端口${port}...`);
    });
  } catch (error) {
    console.log(error);
  }
};
console.log("hey ho");
start();

Login Controller代码

const login = async (req, res) => {
  // ... 省略用户校验等前置逻辑

  const JWTToken = user.JWTCreate();

  attachCookies({ res, cookieContent: JWTToken });
  res.status(StatusCodes.OK).json({
    userData: {
      name: user.name,
      email: user.email,
    },
  });
};

attachCookies工具函数代码

const attachCookies = ({ res, cookieContent }) => {
      res.cookie("JWTToken", cookieContent, {
        httpOnly: true,
        expires: new Date(Date.now() + 8 * 3600000), // 8小时过期
        secure: process.env.NODE_ENV === "production",
      });
    };
    
export default attachCookies;

前端RTK-Query配置

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

export const apiSlice = createApi({
  reducerPath: "api",
  baseQuery: fetchBaseQuery({ baseUrl: "http://api.xyz.com/api/v1" }),
  tagTypes: ["Tasks", "Diary", "Logout"],
  endpoints: (builder) => ({
    // 用户相关API
    loginUser: builder.mutation({
      query: (initialUser) => ({
        url: "/auth/login",
        method: "POST",
        body: initialUser,
      }),
    }),
    // ... 省略其他端点配置
  });

已尝试但无效的解决方法

  • 在Nginx配置中添加Access-Control-Allow-Origin
  • 在Nginx配置中添加Access-Control-Allow-Methods
  • 在RTK-Query的fetchBaseQuery中设置credentials: "include"
  • 修改attachCookies中的HttpOnly为false
  • 修改attachCookies中的SameSite为"lax"

疑问

  1. 为什么浏览器不保存服务器发送的Cookie?
  2. 为什么Postman能正常工作,但本地运行及S3部署的前端均无法正常操作?
  3. 针对当前架构,有哪些具体的配置调整建议?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:54:57