尝试使用expressjs和react在渲染上托管我的项目时遇到cors错误。使用本地主机时一切正常,但更改网址以匹配站点会引发此错误:
从源“https://book-listing-app.onrender.com”访问“https://book-listing-app-api.onrender.com/login”处的 XMLHttpRequest 已被 CORS 策略阻止:否“ Access-Control-Allow-Origin' 标头存在于请求的资源上。
我尝试在请求中手动添加标头,并使用 fetch 而不是 axios,以防出现默认配置问题,但我仍然遇到某种类型的 cors 错误阻止。
function Login() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [redirect, setRedirect] = useState(false);
async function loginUser(e) {
e.preventDefault();
try {
const response = await axios.post(
`${process.env.REACT_APP_SERVER_URL}/login`,
{
username: username,
password: password,
},
{
withCredentials: true,
// headers: {
// "Access-Control-Allow-Origin": "https://book-listing-app.onrender.com",
// },
}
);
// const response = await fetch(
// `${process.env.REACT_APP_SERVER_URL}/login`,
// {
// method: "POST",
// headers: { "Content-Type": "application/json"},
// body: JSON.stringify({
// username: username,
// password: password,
// }),
// credentials: 'include'
// }
// );
if (response.status === 200) {
setRedirect(true);
}
} catch (err) {
if (err.response.status === 401) {
alert("Invalid username or password");
}
}
}
我还尝试在后端的 cors 配置中添加其他选项,并使用 res.set() 在“/login”方法中手动设置标头。这两种方法仍然显示被 cors 错误阻止。
const cors = require("cors");
app.use(cors({ credentials: true, origin: 'https://book-listing-app.onrender.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['content-type', 'Authorization', 'token'], }));
// app.options('/login', cors());
app.post("/login", (req, res) => {
try {
const { username, password } = req.body;
console.log(username, password);
if (!username || !password) {
return res.status(400).json({ error: "Username and password are required" });
}
const q = "SELECT * FROM book_store.users WHERE username = ?";
db.query(q, [username], (err, data) => {
console.log("Query Error:", err);
console.log("Query Result:", data);
if (err) {
console.log(data);
}
if (data.length === 1) {
const { id, username, password: storedPass } = data[0];
console.log("Entered password:", password);
console.log("Stored hashed password:", storedPass);
const passMatch = bcrypt.compareSync(password, storedPass);
if (passMatch) {
jwt.sign(
{
id,
username,
},
secret,
{
expiresIn: "1h",
},
(err, token) => {
if (err) {
console.log(err);
} else {
// res.set('Access-Control-Allow-Origin', 'https://book-listing-app.onrender.com');
res.cookie("token", token).json({ id, username });
}
}
);
}
} else {
res.status(401).json({ error: "Invalid username or password" });
}
});
} catch (err) {
console.error(err);
return res.status(500).json({ message: "Internal server error" });
}
});
此外,我已经联系了渲染,他们说他们的网站不会影响 cors,所以这绝对是代码的问题。我尝试将其托管在 azure 上以确认这一点,但得到了相同的 cors 错误。
CORS 标头需要位于响应中,而不是请求中。 CORS 的目标是让服务器决定哪些域可以访问数据(对于兼容 CORS 的浏览器)。