Post 请求 Node.js 和 React 的 CORS 错误
Posted
技术标签:
【中文标题】Post 请求 Node.js 和 React 的 CORS 错误【英文标题】:CORS error for Post requests Node.js and React 【发布时间】:2021-11-02 11:17:29 【问题描述】:我对代码的 get 请求有效,但是当涉及到 post 请求时,我收到一个 cors 错误:
CORS 策略已阻止从源“client.com”访问“api.com”处的 XMLHttpRequest:请求的资源上不存在“Access-Control-Allow-Origin”标头。
我已经尝试了所有与解决此问题相关的方法,但我一直得到相同的结果。我想知道是不是因为我的套接字服务器?很郁闷。
我的节点代码:
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const session = require("cookie-session");
const cors = require("cors");
const server = require("http").createServer(app);
const rateLimit = require("express-rate-limit");
const io = require("socket.io")(server,
cors:
origin: "*",
,
);
const multer = require('multer');
const v4: uuidv4 = require('uuid');
let path = require('path');
app.use(bodyParser.urlencoded( extended: true ));
app.use(bodyParser.json());
app.use(
session(
resave: false,
saveUninitialized: true,
secret: "shhhhhh",
)
);
app.use(function (req, res, next)
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
);
app.use(cors());
const
registerTeacher,
loginTeacher,
getOneTeacher,
getAllTeachers,
postAvailibility,
deleteExpired
= require("./teachers");
const
loginStudent,
registerStudent,
getOneStudent,
bookTeacher,
= require("./students");
const postMessage, getMessages = require("./classes");
///images
const storage = multer.diskStorage(
destination: function(req, file, cb)
cb(null, 'images');
,
filename: function(req, file, cb)
cb(null, uuidv4() + '-' + Date.now() + path.extname(file.originalname));
);
const fileFilter = (req, file, cb) =>
const allowedFileTypes = ['image/jpeg', 'image/jpg', 'image/png'];
if(allowedFileTypes.includes(file.mimetype))
cb(null, true);
else
cb(null, false);
let upload = multer( storage, fileFilter );
////teacher routes
app.post("/api/teachers/register", upload.single('photo'), registerTeacher);
app.post("/api/teachers/login", loginTeacher);
app.get("/api/teachers/:teacherId", getOneTeacher);
app.post("/api/teachers/:teacherId/calender", postAvailibility);
app.delete("/api/teachers/:teacherId/calender", deleteExpired)
///student routes
app.post("/api/students/register", upload.single('photo'), registerStudent);
app.post("/api/students/login", loginStudent);
app.get("/api/students/:studentId", getOneStudent);
app.get("/api/students/:studentId/ourteachers", getAllTeachers);
app.post("/api/students/:studentId/ourteachers/:teacherId", bookTeacher);
///Class Routes for getting messages only
app.put("/api/:classId/:studentId/:teacherId", postMessage);
app.get("/api/:classId/:studentId/:teacherId", getMessages);
////socket
let users = [];
const addUser = (userId, socketId) =>
!users.some((user) => user.userId === userId) &&
users.push( userId, socketId );
;
const removeUser = (socketId) =>
users = users.filter((user) => user.socketId !== socketId);
;
const getUser = (userId) =>
return users.find((user) => user.userId === userId);
;
io.on("connection", (socket) =>
///connected
///take userId and socketId
socket.on("addUser", (userId) =>
addUser(userId, socket.id);
io.emit("getUsers", users);
);
///send and get message
socket.on("sendMessage", ( senderId, receiverId, text ) =>
const user = getUser(receiverId);
io.to(user.socketId).emit("getMessage",
senderId,
text,
);
);
socket.emit("me", socket.id);
socket.on("callUser", (data) =>
io.to(data.userToCall).emit("callUser",
signal: data.signalData,
from: data.from,
name: data.name,
);
);
socket.on("answerCall", (data) =>
io.to(data.to).emit("callAccepted", data.signal);
);
///for mouse
socket.on("sendLines", (data) =>
io.to(data.to).emit("getLines", data.lines);
);
socket.on("clearLines", (data) =>
io.to(data.to).emit("getClearLines", data.lines);
);
///for slides
socket.on('sendSlidePosition', (data)=>
io.to(data.to).emit('getSlidePosition', data.slidePosition)
)
socket.on('sendAllow', (data)=>
io.to(data.to).emit('getAllow', data.data)
)
///disconnected
socket.on("disconnect", () =>
console.log("User disconnected");
removeUser(socket.id);
io.emit("getUsers", users);
);
);
let port = process.env.PORT;
if (port == null || port == "")
port = 5000;
server.listen(port, function ()
console.log("Successful port connection");
);
我的反应代码:
import useState from "react";
import axios from "axios";
import useHistory from "react-router-dom";
import FormControl, Input, Button from "@material-ui/core";
function TeacherSignup()
let history = useHistory();
const url =
"myapi.com";
const [data, setData] = useState(
name: "",
email: "",
age: "",
phoneNumber: "",
nationality: "",
country: "",
city: "",
street: "",
postalCode: "",
password: "",
confirmPassword: "",
);
function submit(e)
e.preventDefault();
if (data.password !== data.confirmPassword)
alert("passwords must match");
axios
.post(url,
name: data.name,
email: data.email,
age: data.age,
phoneNumber: data.phoneNumber,
country: data.country,
city: data.city,
street: data.street,
password: data.password,
postalCode: data.postalCode,
nationality: data.nationality,
)
.then((res) =>
console.log(res.data._id);
history.push(`/teachers/$res.data._id`);
);
function handle(e)
const newData = ...data ;
newData[e.target.id] = e.target.value;
setData(newData);
console.log(newData);
return (
<div className='login-form'>
<h1>Register Teacher</h1>
<form onSubmit=(e) => submit(e)>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="name"
value=data.name
placeholder="Name"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="email"
value=data.email
placeholder="Email"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="age"
value=data.age
placeholder="Age"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="phoneNumber"
value=data.phoneNumber
placeholder="Phone Number"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="nationality"
value=data.nationality
placeholder="Nationality"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="country"
value=data.country
placeholder="Country"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="city"
value=data.city
placeholder="City"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="street"
value=data.street
placeholder="Street"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="postalCode"
value=data.postalCode
placeholder="Postal Code"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="password"
value=data.password
placeholder="Password"
type="text"
></Input>
</FormControl>
</div>
<div className="login-input">
<FormControl>
<Input
onChange=(e) => handle(e)
id="confirmPassword"
value=data.confirmPassword
placeholder="Confirm Password"
type="text"
></Input>
</FormControl>
</div>
<Button type="submit">Submit</Button>
</form>
</div>
);
export default TeacherSignup;
【问题讨论】:
为什么要在app.use(cors())
调用之前明确设置 CORS 响应标头?我会尝试删除它,因为它可能与 cors
冲突。
我不想挑剔,但错误是提到 api.com
并且您的反应服务器正在连接到 myapi.com
这只是一个错字还是这两个不同的服务器?
您可以尝试删除app.use(cors())
并在您的自定义cors 处理程序(即res.header.set("Access-Control-Allow-Origin", "*")
)中设置一个断点以查看该断点是否被命中?如果它被命中,则检查该特定请求的响应是否包含 ACAO 标头。如果不是(如错误所示),还有其他东西会干扰您的响应并可能重置标题...
如果断点未命中,则说明您的服务器设置存在其他问题,无法执行所有中间件。然后你应该尝试将你的服务器减少到一个最小的例子。例如尝试删除socket.io
和其他中间件并检查问题是否仍然存在......如果你有工作配置,添加回各个部分,看看问题是否再次出现......
你能不能也检查一下浏览器,如果有预检(OPTIONS)请求被发送,如果是,这个请求的结果是什么...
【参考方案1】:
我将删除在 app.use(cors())
之前设置的显式 CORS 标头,并将 methods: ['GET', 'POST', 'DELETE', 'OPTIONS']
添加到您的 io
配置中。
从 Socket.IO v3 开始,您需要显式启用跨域资源共享 (CORS)。
【讨论】:
我试过了,还是不行。同样的错误 很难说没有关于确切错误消息的更多信息。确保支持预检请求:app.options('*', cors())
.
您可能还试图传递您的cors
配置不接受的凭据或自定义标头。你能指出确切的错误吗?以上是关于Post 请求 Node.js 和 React 的 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章