将套接字从电子 UI 连接到 python 服务器时出现错误 400(错误请求)

Posted

技术标签:

【中文标题】将套接字从电子 UI 连接到 python 服务器时出现错误 400(错误请求)【英文标题】:Error 400 (Bad Request) when connecting socket from electron UI to python server 【发布时间】:2019-12-27 05:39:48 【问题描述】:

我在使用 Web 套接字加入 Electron 和 Python 时遇到了一些问题(主要是作为学习经验):

使用 Electron 构建桌面应用Ok

构建一个 Python 程序来监控一些事情 好的

使用 socket.io 将 Python 与 Electron 连接 不工作

首先,我使用https://github.com/miguelgrinberg/python-socketio/tree/master/examples/server/aiohttp 中的“延迟”示例在 python 中测试了 socket.io。当我在 Chrome 中查看 http://localhost:8080/ 时,效果很好。

下一步是让 Electron 在桌面应用程序中使用 mainWindow.loadURL('http://localhost:8080') 加载相同的 url(我使用了来自官方 electron-quick-start 示例的模板)。我只需要在 html 中添加两行,如下所示:Electron: jQuery is not defined 让 jquery 在 Electron 中正确加载,但它再次运行良好。

现在我尝试创建一个与latency.html 内容相同的index.html,并使用mainWindow.loadFile('gui/index.html') 加载它。我将var socket = io.connect(); 更改为var socket = io.connect('ws://localhost:8080');(我也尝试过ws://127.0.0.1:8080ws://192.168.<x>.<x>:8080)。 html 文件正确加载,但套接字开始重复连接和断开连接并出现错误请求错误(我添加了两个 console.log 行):

(console.log) connected
(error)       POST http://localhost:8080/socket.io/?EIO=3&transport=polling&t=MosNuF3&sid=c62ce5a6090c4b72bf3f7c6916da6ce7 400 (Bad Request)   **polling-xhr.js:264**
(console.log) disconnected
(warning)     websocket.js:235 WebSocket connection to 'ws://localhost:8080/socket.io/?EIO=3&transport=websocket&sid=c62ce5a6090c4b72bf3f7c6916da6ce7' failed: WebSocket is closed before the connection is established.
(error)       POST http://localhost:8080/socket.io/?EIO=3&transport=polling&t=MosNuFS&sid=c62ce5a6090c4b72bf3f7c6916da6ce7 400 (Bad Request)   **polling-xhr.js:264**
(console.log) connected
etc...
(console.log) disconnected
etc...

在服务器端,当我停止 Electron 应用程序时也出现错误:

Unhandled exception
Traceback (most recent call last):
  File "D:\Programming\Tools\Anaconda3\lib\site-packages\aiohttp\web_protocol.py", line 447, in start
    await resp.prepare(request)
  File "D:\Programming\Tools\Anaconda3\lib\site-packages\aiohttp\web_response.py", line 353, in prepare
    return await self._start(request)
  File "D:\Programming\Tools\Anaconda3\lib\site-packages\aiohttp\web_response.py", line 667, in _start
    return await super()._start(request)
  File "D:\Programming\Tools\Anaconda3\lib\site-packages\aiohttp\web_response.py", line 410, in _start
    await writer.write_headers(status_line, headers)
  File "D:\Programming\Tools\Anaconda3\lib\site-packages\aiohttp\http_writer.py", line 112, in write_headers
    self._write(buf)
  File "D:\Programming\Tools\Anaconda3\lib\site-packages\aiohttp\http_writer.py", line 67, in _write
    raise ConnectionResetError('Cannot write to closing transport')
ConnectionResetError: Cannot write to closing transport

在这种情况下,这个 Bad Request 错误是什么意思?连接如何正常工作?

谢谢。

【问题讨论】:

【参考方案1】:

如果有人遇到同样的问题。答案很简单,来自 socket.io here 的文档:

出于安全原因,此服务器通过以下方式强制执行同源策略 默认。实际上,这意味着:

如果传入的 HTTP 或 WebSocket 请求包含 Origin 标头,则此标头必须与连接的方案和主机匹配 网址。如果不匹配,则返回 400 状态码响应,并且 连接被拒绝。 对不包含 Origin 标头的传入请求没有任何限制。

如有必要,可使用 cors_allowed_origins 选项来允许 其他来源。该参数可以设置为一个字符串来设置单个 允许的来源,或列表以允许多个来源。一个特别的 '*' 的值可用于指示服务器允许所有来源, 但这应该小心完成,因为这可能会使服务器 容易受到跨站请求伪造 (CSRF) 攻击。

使用 electron 加载 gui 时,服务器与执行监控的 python 服务器不同,因此出现错误请求(来源不同)。解决办法就是修改如下服务器属性添加cors_allowed_origins='*':

socketio.AsyncServer(async_mode='aiohttp', cors_allowed_origins='*')

【讨论】:

是的,就是这样,非常感谢您的解决方案!

以上是关于将套接字从电子 UI 连接到 python 服务器时出现错误 400(错误请求)的主要内容,如果未能解决你的问题,请参考以下文章

从 reactjs 客户端连接到安全 Web 套接字 python 服务器

如何从服务器发送请求断开连接到所有客户端和服务器仍然存在(python套接字)

android中的python套接字无法连接到在virtualbox中运行的python服务器

连接到 ngrok 服务器的 python 套接字

Python套接字通过端口转发连接到服务器

使用 python 套接字发送/接收数据