使用JWT时,Express返回res.cookie后Post请求处于Pending状态
问题原因与解决方案
你的请求一直处于Pending状态的核心原因是:res.cookie()仅负责在响应头中设置Cookie,并不会主动结束HTTP响应。Express需要明确的响应结束指令(比如res.send()、res.json()或res.end()),否则服务器会一直保持连接,等待发送响应体,导致浏览器请求挂起。
另外,跨域场景下Cookie的传递还需要额外配置CORS和前端请求参数,否则即使设置了Cookie,浏览器也不会保存。
具体修复步骤
1. 服务器端:设置Cookie后必须结束响应
修改/login路由,在res.cookie()之后添加响应体发送方法,比如res.json():
server.post("/login", async (req, res) => { const { username, password } = req.body; const data = await db.getData("/users"); const user = data.find((user) => { return user.username === username && user.password === password; }); if (!user) { return res.status(403).json({ error: "invalid login", }); } const token = jwt.sign(user, process.env.MY_SECRET, { expiresIn: "1h" }); // 设置Cookie后,发送响应体结束请求 return res.cookie("token", token, { httpOnly: true }).json({ success: true, message: "登录成功" }); });
2. 服务器端:配置CORS允许凭证传递
跨域场景下,需要让CORS允许携带凭证(Cookie),修改cors中间件配置:
// 替换原来的server.use(cors()) server.use(cors({ credentials: true, origin: "http://localhost:3001" // 替换为你的React应用运行地址 }));
3. 前端:请求时携带凭证
修改Axios请求,添加withCredentials: true参数,确保浏览器发送请求时携带Cookie:
const handleSubmit = async () => { const username = usernameRef.current.value; const password = passwordRef.current.value; const response = await axios.post("http://localhost:3000/login", { username: username, password: password, }, { withCredentials: true // 新增配置 }); console.log(response); };
补充说明
res.cookie()只是操作响应头,属于"准备响应"的步骤,而非"完成响应";而res.send()、res.json()会同时设置响应体并结束HTTP连接,所以之前用res.send时一切正常。- 若不需要返回数据,也可以用
res.end()直接结束响应,但通常返回一个成功状态的JSON更符合前后端交互规范。
内容的提问来源于stack exchange,提问作者CoffeeSlurper
相关产品推荐
相关产品推荐

