客户端和服务器端(React/Node.js)之间的 Socket.io 连接失败

Posted

技术标签:

【中文标题】客户端和服务器端(React/Node.js)之间的 Socket.io 连接失败【英文标题】:Socket.io connection fails between client and server side (Reacr/Node.js) 【发布时间】:2020-06-20 20:09:21 【问题描述】:

我正在尝试建立一个基本的套接字连接。

服务器如下所示:

    const express = require("express");
    const app = express();
    const port = 4000;
    const server = require("http").createServer(app);
    let io = require("socket.io")(server);

    app.get("/", (req, res) => res.send("Server up"));

    io.on("connection", socket => 
      console.log("a user connected");
    );

    app.get("/", (req, res) => res.send("Hello World!"));

    app.listen(port, () => console.log(`Example app listening on port $port!`));

React 组件如下所示:

    import React,  useState, useEffect  from "react";
    import io from "socket.io-client";

    const ChatScreen = () => 

      const socket = io('localhost:4000');


      useEffect(() => 
      , []);

      return (
        <div className="chatScreen">HI</div>
      );
    ;

    export default ChatScreen;

正如我从阅读中得到的,我应该在服务器中获得一个 console.log “用户已连接”。 但我得到了这两个错误:

Access to XMLHttpRequest at 'http://localhost:4000/socket.io/?EIO=3&transport=polling&t=N2xxl7i' 
from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-
Origin' header is present on the requested resource.

polling-xhr.js:267 GET http://localhost:4000/socket.io/?EIO=3&transport=polling&t=N2xy65_ 
net::ERR_FAILED

我该怎么做?

【问题讨论】:

【参考方案1】:

在你的 node js 应用中,你可以尝试在var app = express(); 后面添加以下内容:

app.use(function(req, res, next) 
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header("Access-Control-Allow-Headers", "Content-Type");
  res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
  next();
);

【讨论】:

【参考方案2】:

此错误表示您的 Express 服务器不允许任何外部请求。你的 React 服务器是一个外部服务器,这就是这个错误的原因。

要修复此错误,只需将cors middleware 用作:

const express = require("express");
const cors= require("cors");
const app = express();
const port = 4000;
const server = require("http").createServer(app);
let io = require("socket.io")(server);

app.use(cors());

app.get("/", (req, res) => res.send("Server up"));

io.on("connection", socket => 
  console.log("a user connected");
);

app.get("/", (req, res) => res.send("Hello World!"));

app.listen(port, () => console.log(`Example app listening on port $port!`));

文档: https://expressjs.com/en/resources/middleware/cors.html

【讨论】:

谢谢你。做到了,现在它给出了另一个错误:从源“localhost:3000”访问 XMLHttpRequest 在“localhost:4000/socket.io/…”已被 CORS 策略阻止:响应中的“Access-Control-Allow-Origin”标头的值必须当请求的凭据模式为“包含”时,不是通配符“*”。 XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制。有什么想法吗? 听起来很奇怪。也许试着看看 cors 的配置,你应该可以很容易地从那里修复它。

以上是关于客户端和服务器端(React/Node.js)之间的 Socket.io 连接失败的主要内容,如果未能解决你的问题,请参考以下文章

Electron + React + Node.js + ES6 开发桌面软件

Electron + React + Node.js + ES6 开发桌面软件

Electron + React + Node.js + ES6 开发本地 App

在客户端和服务器端格式之间转换数据的正确术语是啥?

在 react (Node.JS) 中使用繁重/耗时的函数

Socket(套接字)在服务器端和客户端之间的基本工作原理