【问题标题】:Acces-Control-Allow-Origin with Grunt Server and Flask SocketIO-app使用 Grunt 服务器和 Flask SocketIO-app 的 Access-Control-Allow-Origin
【发布时间】:2013-10-15 21:47:13
【问题描述】:

我在尝试连接我的 Angular 应用程序时收到以下错误消息,使用 Grunt 服务器运行,使用 socketIO Flask 应用程序:

XMLHttpRequest cannot load http://localhost:8080/socket.io/1/?t=1381872821951. 
Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.

我已经对这个问题进行了一些研究,我知道这是因为客户端 (angularjs) 正在向另一个服务器发出请求,而响应来自该服务器。

两台服务器中的哪一台有问题?

1) Grunt 服务器?我已经试过了:https://stackoverflow.com/a/17256255/1819058 如果它来自 Grunt 服务器,哪个应该可以解决问题

2) Flask SocketIO 服务器:

app = Flask(__name__)

@app.route("/socket.io/<path:path>")
def run_socketio(path):
    socketio_manage(request.environ, {'': ChatNamespace})

if __name__ == '__main__':
    print 'Listening on http://localhost:8080'
    app.debug = True
    import os
    from werkzeug.wsgi import SharedDataMiddleware
    app = SharedDataMiddleware(app, {
        '/': os.path.join(os.path.dirname(__file__), 'static')
        })
    from socketio.server import SocketIOServer
    SocketIOServer(('', 8080), app,
        namespace="socket.io", policy_server=False).serve_forever()

这是我连接到服务器的方式:

var socket = ioSocket || io.connect('http://localhost:8080');

有人可以帮我解决这个问题吗?如果您使用 websockets,请求转到另一台服务器不是逻辑吗?

另一个奇怪的注意事项:整个事情都有效,但在重新启动后停止工作......

【问题讨论】:

    标签: angularjs websocket socket.io flask gruntjs


    【解决方案1】:

    您需要分配自己的 SocketIOHandler。首先你需要修复 SocketIOServer 中的 init

    class CorsServer(SocketIOServer):
        def __init__(self, *args, **kwargs):
            self.sockets = {}
            if 'resource' in kwargs:
                print "DEPRECATION WARNING: use `namespace` instead of `resource`"
            self.namespace = kwargs.pop('resource', kwargs.pop('namespace',
                                                               'socket.io'))
            self.transports = kwargs.pop('transports', None)
    
            if kwargs.pop('policy_server', True):
                self.policy_server = FlashPolicyServer()
            else:
                self.policy_server = None
            #fix
            if 'handler_class' not in kwargs:
                kwargs['handler_class'] = SocketIOHandler
            super(SocketIOServer, self).__init__(*args, **kwargs)
    

    然后制作自己的SocketIOHandler

    class CorsHandler(SocketIOHandler):
        def write_plain_result(self, data):
            self.start_response("200 OK", [
                ("Access-Control-Allow-Origin", self.environ.get('HTTP_ORIGIN', '*')),
                ("Access-Control-Allow-Credentials", "true"),
                ("Access-Control-Allow-Methods", "POST, GET, OPTIONS"),
                ("Access-Control-Max-Age", 3600),
                ("Content-Type", "text/plain"),
            ])
            self.result = [data]
    

    初始化Flask,添加路由

    app = Flask(__name__)
    @app.route("/socket.io/<path:path>")
    def run_socket(param):
        socketio_manage(request.environ, {'': YourNamespace})
    

    用你的 CorsHandler 初始化你的 CorsServer

    if __name__ == "__main__":    
        server = CorsServer(('0.0.0.0', 8080), app,
            namespace="socket.io",handler_class=CorsHandler).serve_forever()
    

    【讨论】:

      【解决方案2】:

      看看这个帖子:http://flask.pocoo.org/snippets/56/

      在这里您会看到如何为 Acces-Control-Allow-Origin 设置通配符

      【讨论】:

      • 我试过这个。我用这个装饰器装饰了 @app.route("/socket.io/") 路由,但它不起作用。这是否意味着是烧瓶应用不允许 CORS 而不是 Grunt 服务器?
      • Grunt 正在尝试连接 de flask 应用,所以问题确实是 flask 应用不允许 CORS
      猜你喜欢
      • 1970-01-01
      • 2014-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-13
      • 2014-06-07
      • 2016-09-30
      • 1970-01-01
      相关资源
      最近更新 更多