添加Socket.io后Express项目仍出现CORS跨域错误求助
问题
我在Express项目中已配置CORS响应头,代码如下:
const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, "images"); }, filename: function (req, file, cb) { cb(null, uuidv4()); }, }); const fileFilter = (req, file, cb) => { if ( file.mimetype === "image/png" || file.mimetype === "image/jpg" || file.mimetype === "image/jpeg" || file.mimetype === "image/jfif" ) { cb(null, true); } else { cb(null, false); } }; app.use(bodyParser.json()); // application/json app.use(multer({ storage: storage, fileFilter: fileFilter }).single("image")); app.use("/images", express.static(path.join(__dirname, "images"))); app.use((req, res, next) => { res.setHeader("Access-Control-Allow-Origin", "*"); res.setHeader( "Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,PATCH,DELETE" ); res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); next(); }); app.use("/feed", feedRoutes); app.use("/auth", authRoutes); app.use((error, req, res, next) => { console.log(error); const status = error.statusCode || 500; const message = error.message; const data = error.data; res.status(status).json({ message: message, data: data }); });
但添加Socket.io并运行以下代码后,出现CORS错误:
mongoose .connect( "mydatabase" ) .then((result) => { const server = app.listen(8080); const io = require("socket.io")(server); console.log('listening'); io.on('connection', (stream) => { console.log('Connected'); }); }) .catch((err) => console.log(err));
错误信息:
Access to XMLHttpRequest at 'http://localhost:8080/socket.io/?something' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
明明已设置CORS头却仍报错,求解决方法。
解决方法
原因:通过Express中间件设置的CORS规则仅对普通HTTP请求生效,Socket.io建立连接时的握手请求(含后续轮询请求)不会走这些Express中间件,需单独为Socket.io配置CORS规则。
修改步骤:
初始化Socket.io时传入CORS配置选项,示例如下:const io = require("socket.io")(server, { cors: { origin: "http://localhost:3000", // 允许的前端域名,生产环境建议指定具体域名而非"*" methods: ["OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE"], allowedHeaders: ["Content-Type", "Authorization"], credentials: true // 若需携带Cookie等凭证,开启此选项 } });如果需要保持和Express中一致的宽松规则,也可以直接设置:
const io = require("socket.io")(server, { cors: { origin: "*", methods: ["OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE"], allowedHeaders: ["Content-Type", "Authorization"] } });验证:重启服务器后,前端Socket.io连接即可正常建立,CORS错误会消失。
内容的提问来源于stack exchange,提问作者Mahdi Zolfaghari
相关产品推荐
相关产品推荐

