获取代码:调用登录 API 时为"ERR_HTTP_HEADERS_SENT"



我面临的错误是,在提交登录表单之前,我能够顺利地从mongo数据库中获取数据。在提交登录表格时,我会收到一个错误

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:372:5)
at ServerResponse.setHeader (node:_http_outgoing:576:11)
at ServerResponse.header (E:Blog-Websiteapinode_modulesexpresslibresponse.js:794:10)
at ServerResponse.send (E:Blog-Websiteapinode_modulesexpresslibresponse.js:174:12)
at ServerResponse.json (E:Blog-Websiteapinode_modulesexpresslibresponse.js:278:15)
at E:Blog-Websiteapiroutesauth.js:37:23
at processTicksAndRejections (node:internal/process/task_queues:96:5) { 
code: 'ERR_HTTP_HEADERS_SENT'

我搜索了很多,基本上是按照教程创建我的第一个MERN项目。但是我不知道哪一个标头被重复发送。

下面是我的后端auth.js代码

const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require('bcrypt');
//REGISTER
router.post("/register", async (req, res) => {
try {
const salt = await bcrypt.genSalt(10);
const hashedPass = await bcrypt.hash(req.body.password, salt);
const newUser = new User({
username: req.body.username,
email: req.body.email,
password: hashedPass,
});
const user = await newUser.save();
console.log(user)
res.status(200).json(user);
} catch (err) {
res.status(500).json(err);
}
});
//LOGIN
router.post("/login", async (req, res) => {
try {
const user = await User.findOne({ username: req.body.username });
!user && res.status(400).json("Wrong credentials!");
const validated = await bcrypt.compare(req.body.password, user.password);
!validated && res.status(400).json("Wrong credentials!");
const { password, ...others } = user._doc;
res.status(200).json(others);
} catch (err) {
res.status(500).json(err);
}
});

module.exports = router

下面是我的前端代码登录。jsx

import { Link } from "react-router-dom";
import "./login.css"
import { useContext, useRef } from "react";
import axios from "axios";
import { Context } from "../../../context/Context";
export default function Login() {
const userRef = useRef();
const passwordRef = useRef();
const { user, dispatch, isFetching } = useContext(Context);

const handleSubmit = async (e) => {
e.preventDefault();
dispatch({ type: "LOGIN_START" });
try {
const res = await axios.post("/auth/login", {
username: userRef.current.value,
password: passwordRef.current.value,
});
dispatch({ type: "LOGIN_SUCCESS", payload: res.data });
} catch (err) {
dispatch({ type: "LOGIN_FAILURE" });
}
};
console.log(user)
return (
<div className="login">
<span className="loginTitle">Login</span>
<form className="loginForm" onSubmit={handleSubmit}>
<label>Username</label>
<input className="loginInput" type="text" placeholder="Enter your username..." ref= 
{userRef} />
<label>Password</label>
<input className="loginInput" type="password" placeholder="Enter your password..." ref= 
{passwordRef} />
<button className="loginButton" type="submit">Login</button>
</form>
<button className="loginRegisterButton">
<Link className="link" to="/register">Register</Link>
</button>
</div>
);
}

我已经在谷歌上搜索了4个小时,但我仍然不知道我的错误是从哪里来的!!

非常感谢任何帮助

我认为错误位于以下几行:

const user = await User.findOne({ username: req.body.username });
!user && res.status(400).json("Wrong credentials!");
const validated = await bcrypt.compare(req.body.password, user.password);
!validated && res.status(400).json("Wrong credentials!");

当找不到用户时调用res.status(...不会中断执行——它将前进到res.status(200).json(others),后者将向客户端发送另一组标头。

要解决此问题,您可以简单地添加return语句,如下所示:

const user = await User.findOne({ username: req.body.username });
if (!user)
return res.status(400).json("Wrong credentials!");
const validated = await bcrypt.compare(req.body.password, user.password);
if (!validated)
return res.status(400).json("Wrong credentials!");

这样,执行在出现错误时停止,并且res.status(...只被调用一次。

最新更新