将套接字从电子 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:8080
和ws://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套接字)