携带Credentials的POST/GET请求无法发送Cookie问题求助
我知道这个问题存在诸多重复提问,但已尝试所有相关方案均无效,因此发起新提问。除axios外,还尝试使用fetch,结果一致。
后端环境与代码
依赖
- "express": "^4.18.2"
- "cors": "^2.8.5"
代码
const express = require("express"); const cors = require("cors"); const jwt = require("jsonwebtoken") const cookieParser = require('cookie-parser') require("dotenv").config(); const allowedOrigins = [ 'http://127.0.0.1:5173', 'http://localhost:5173', ]; const headers = (req, res, next) => { const origin = req.headers.origin; if (allowedOrigins.includes(origin)) { res.setHeader('Access-Control-Allow-Origin', origin) res.setHeader('Access-Control-Allow-Methods', 'GET, POST') res.setHeader('Access-Control-Allow-Credentials', true); } next(); } const corsOptions = { origin: allowedOrigins, credentials: true, optionsSuccessStatus: 200 } app.use(headers); app.use(cors(corsOptions)) app.use(express.json()) app.use(cookieParser()) app.post("/foo", (req,res) => { const token = jwt.sign( { 'foo': "qwerty" }, process.env.JWT_SECRET, { expiresIn: '1d' } ) res.cookie( 'jwt', token, { httpOnly: true, secure: true, sameSite: 'None', maxAge: 24 * 60 * 60 * 1000 } ); } app.get("/bar", (req,res) => { const cookies = req.cookies console.log(cookies) // 此处始终为 undefined if (!cookies?.jwt) return res.sendStatus(401) // 后续业务逻辑 }
前端环境与代码
依赖
- "react": "^18.2.0"
- "axios": "^1.3.2"
代码
import axios from 'axios'; const app = async () => { const instance = axios.create({ baseURL: "http://127.0.0.1:3001", withCredentials: true // 第一种设置 credentials 的方式 }) instance.defaults.withCredentials = true // 第二种设置 credentials 的方式 const foo = await instance.post("/foo") if (!foo.ok) return const response = await instance.get("/bar", { withCredentials: true // 第三种设置 credentials 的方式 } console.log(response) // 返回 401 }
问题排查与解决方案
1. 移除重复的 CORS 配置
同时使用自定义 headers 中间件和 cors(corsOptions) 会导致响应头冲突,直接删除自定义的 headers 中间件,express-cors 会自动处理正确的跨域头。
2. 修正 Cookie 的 secure 属性
本地开发使用 HTTP 协议,但设置了 secure: true,该属性要求 Cookie 仅在 HTTPS 环境下传输。修改为 secure: process.env.NODE_ENV === 'production',让生产环境(HTTPS)才启用该属性,本地 HTTP 环境也能正常传递 Cookie。
3. 确保接口返回响应
/foo 接口仅设置了 Cookie 但未发送响应,会导致请求挂起,前端无法正确接收 Cookie。在 /foo 接口末尾添加 res.sendStatus(200)。
4. 修正 axios 请求的判断逻辑
axios 响应对象没有 ok 属性,应使用 foo.status === 200 判断请求是否成功。
修改后的关键代码
后端代码调整
// 删除自定义 headers 中间件 // app.use(headers); app.use(cors(corsOptions)) app.use(express.json()) app.use(cookieParser()) app.post("/foo", (req,res) => { const token = jwt.sign( { 'foo': "qwerty" }, process.env.JWT_SECRET, { expiresIn: '1d' } ) res.cookie( 'jwt', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', // 生产环境启用 sameSite: 'None', maxAge: 24 * 60 * 60 * 1000 } ); res.sendStatus(200); // 添加响应 }) app.get("/bar", (req,res) => { const cookies = req.cookies console.log(cookies) if (!cookies?.jwt) return res.sendStatus(401) res.sendStatus(200) // 添加测试响应 })
前端代码调整
import axios from 'axios'; const app = async () => { try { const instance = axios.create({ baseURL: "http://127.0.0.1:3001", withCredentials: true }) const foo = await instance.post("/foo") if (foo.status !== 200) return const response = await instance.get("/bar") console.log(response) // 应返回 200 } catch (err) { console.error(err) } }
内容的提问来源于stack exchange,提问作者juniortan
相关产品推荐
相关产品推荐

