我正在开发一个预订应用程序,并尝试实现身份验证,因此当我从 Postman 发送POST请求时,我会获得用户信息,但当使用axios库从react应用程序发送POST请求时,我会收到404未找到错误
这是登录中不同事件的AuthContext页面
import { createContext, useEffect, useReducer } from "react";
const INITIAL_STATE = {
user: JSON.parse(localStorage.getItem("user")) || null,
loading: false,
error: null,
};
export const AuthContext = createContext(INITIAL_STATE);
const AuthReducer = (state, action) => {
switch (action.type) {
case "LOGIN_START":
return {
user: null,
loading: true,
error: null,
};
case "LOGIN_SUCCESS":
return {
user: action.payload,
loading: false,
error: null,
};
case "LOGIN_FAILURE":
return {
user: null,
loading: false,
error: action.payload,
};
case "LOGOUT":
return {
user: null,
loading: false,
error: null,
};
default:
return state;
}
};
export const AuthContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(AuthReducer, INITIAL_STATE);
useEffect(() => {
localStorage.setItem("user", JSON.stringify(state.user));
}, [state.user]);
return (
<AuthContext.Provider
value={{
user: state.user,
loading: state.loading,
error: state.error,
dispatch,
}}
>
{children}
</AuthContext.Provider>
);
};
这是登录页面代码
import axios from "axios";
import { useContext, useState } from "react";
import { AuthContext } from "../../context/AuthContext";
import { useNavigate } from "react-router-dom";
import "./login.css";
const Login = () => {
const [credentials, setCredentials] = useState({
username: undefined,
password: undefined,
});
const {user, loading, error, dispatch } = useContext(AuthContext);
const navigate = useNavigate();
const handleChange = (e) => {
setCredentials((prev) => ({ ...prev, [e.target.id]: e.target.value }));
};
const handleClick = async (e) => {
e.preventDefault();
dispatch({ type: "LOGIN_START" });
try {
const res = await axios.post("/auth/login", credentials);
dispatch({ type: "LOGIN_SUCCESS", payload: res.data });
navigate("/");
} catch (err) {
dispatch({ type: "LOGIN_FAILURE", payload: err.response.data });
}
};
return (
<div className="login">
<div className="lContainer">
<input
type="text"
placeholder="username"
id="username"
onChange={handleChange}
className="lInput"
/>
<input
type="password"
placeholder="password"
id="password"
onChange={handleChange}
className="lInput"
/>
<button disabled={loading} onClick={handleClick} className="lButton">
Login
</button>
{error && <span>{error.message}</span>}
</div>
</div>
);
};
export default Login;
我使用代理"proxy": "http://localhost:8800/api"
将前端与Express服务器连接
这是package.json文件
{
"name": "hotel-moment",
"version": "0.1.0",
"private": true,
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.2.1",
"@fortawesome/free-regular-svg-icons": "^6.2.1",
"@fortawesome/free-solid-svg-icons": "^6.2.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.2.4",
"date-fns": "^2.29.3",
"http-proxy-middleware": "^2.0.6",
"react": "^18.2.0",
"react-date-range": "^1.4.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.4",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:8800/api"
}
这些是登录路由的控制器
import User from "../models/User.js";
import bcrypt from "bcrypt";
import { createError } from "../utils/error.js";
import jwt from "jsonwebtoken";
// Sign Up user function
export const register = async (req, res, next) => {
try {
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync(req.body.password, salt);
const newUser = new User({
username: req.body.username,
email: req.body.email,
password: hash,
});
await newUser.save();
res.status(200).send("User has been created");
} catch(err) {
next(err);
}
}
// Login user function
export const login = async (req, res, next) => {
try {
const user = await User.findOne({username: req.body.username});
if(!user) return next(createError(404, "User not found"));
const isPasswordCorrect = await bcrypt.compare(req.body.password, user.password);
const token = jwt.sign({ id:user._id, isAdmin: user.isAdmin }, process.env.JWT_TOKEN);
if(!isPasswordCorrect) return next(createError(400, "Incorrct password or username"));
const {password, isAdmin, ...otherDetails} = user._doc;
res
.cookie("access_token", token, {
httpOnly: true,
})
.status(200)
.json({...otherDetails});
} catch(err) {
next(err);
}
}
我尝试使用promises执行相同的操作,但仍然得到相同的错误。我不明白为什么会得到此错误
Error 404 Not Found
但在 Postman 里我得到了这样的回应
Postman respose
请帮我解决这个错误,我会非常感谢你
3条答案
按热度按时间laik7k3q1#
你能试一下下面的代码吗?
ffscu2ro2#
您是否在包.json中添加了代理?
6vl6ewon3#
你的前端和后端都在两个不同的端口上。如果你在谷歌控制台检查你的错误,它会给出http://localhost:3000,但你的后端在http://localhost:8800。现在你需要为axios添加配置。告诉他使用http://localhost:8800。
这里我们添加了http://localhost:8800作为axios的BaseUrl,现在可以在handleClick方法中使用
instance.post("/auth/login", credentials)
您可以为创建Axios示例创建一个单独的文件,并在您想要使用的地方使用它。
现在你可以导入示例而不是axios了,这样就保存每次API调用都配置axios了。