从Python 3套接字服务器发送到Node js Client时发生CORS错误

时间:2019-01-18 02:41:30

标签: python node.js socket.io cors

我已经从以下网址引用了Python3套接字服务器:
https://python-socketio.readthedocs.io/en/latest/intro.html#server-examples
示例代码如下所示:

from aiohttp import web
import socketio
from eventlet.green import subprocess


sio = socketio.AsyncServer()
app = web.Application() 
sio.attach(app)

async def index(request):
with open('index.html') as f:
    return web.Response(text=f.read(), content_type='text/html')

@sio.on('connect')
def connect(sid, environ):
    print("connect ", sid)

@sio.on('message')
async def message(sid, data):
    ## Some processing that involves subprocess Popen
    ## Using p.communicate to store output of subprocess onto the below variable 'out'
    out = (Json data)
    await sio.emit('reply', out,room=sid)

@sio.on('disconnect')
def disconnect(sid):
    print('disconnect ', sid)


app.router.add_get('/', index)

if __name__ == '__main__':
     web.run_app(app)

如代码所示,有一个子进程调用另一个python程序,进行一些处理,然后将输出(json)存储在'out'变量中,然后将其发射到客户端上。 io是用Node js编写的。当python服务器试图将这个json数据发送给js客户端时,我得到一个错误说明:

       请求的资源上没有“ Access-Control-Allow-Origin”标头

我试图在网上找到答案,但找不到我所需要的答案。我在做什么愚蠢的错误?

1 个答案:

答案 0 :(得分:0)

我已经解决了问题。首先,您需要告诉socketio没问题。

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

当sio附加到“ app”时,为socket.io添加路由,带有带有“ ”的cors标头-表示“ Access-Control-Allow-Origin”标头出现在HTTP回复中,带有“ >”表示允许的域。 (您可以根据需要控制允许的域。)

因此,这是所有问题的第1部分。有一部分2。为了提供“ /”或“ /index.html”,您还需要为aiohttp添加相同的cors标头。换句话说,在单行更改之上仅为socket.io添加了cors标头,而不为aiohttp添加了cors标头。

据我所知,为了使aiohttp具有cors标头,您需要添加aiohttp_cors包,导入aiohttp_cors模块,并将cors标头添加到每条路由。将所有路由添加到路由器后,请执行以下操作:

import aiohttp_cors
cors = aiohttp_cors.setup(app)
# app.router.add_routes(routes) if you have routes
# app.router.add_static("/", rootdir) if you want to serve static, and this has to be absolutely the last route since it's the root. Adding any route after this becomes ignored as '/' matches everthing.
for resource in app.router._resources:
  # Because socket.io already adds cors, if you don't skip socket.io, you get error saying, you've done this already.
  if resource.raw_match("/socket.io/"):
    continue
  cors.add(resource, { '*': aiohttp_cors.ResourceOptions(allow_credentials=True, expose_headers="*", allow_headers="*") })

To make this a little easier, I file a request to aiohttp.