Flask-SocketIO and 400 Bad Request

10,873

Solution 1

I got similar 400 issue with React Flask-SocketIO, the issue was due to CORS error. The following code in flask fixed my issue,

socketio = SocketIO(app)
socketio.init_app(app, cors_allowed_origins="*")

Also make sure you are using eventlet or gevent-websocket in your server when you select [websocket] only transport. Gevent doesnt have websocket support so works only with HTTP polling fallback.

Solution 2

The problem was that I was adding the origin host with http instead of https. Everything is working fine.

Share:
10,873
magnoz
Author by

magnoz

Updated on June 14, 2022

Comments

  • magnoz
    magnoz about 2 years

    I'm running a Flask application with socketio to deal with notifications. The Flask app is listening at port 5000 and the client is in 8080.

    the js client is always getting this error:

    VM15520:1 GET http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Mb2_LpO 400 (Bad Request)
    Access to XMLHttpRequest at 'http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Mb2_LpO' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    

    I'm actually starting my app with gunicorn as follows:

    gunicorn --workers=1 --worker-class eventlet --certfile=keys/key.crt --keyfile=keys/key.key --bind 0.0.0.0:5000 myapp.run:app
    

    and this is my run.py:

    import eventlet
    from myapp import create_app
    eventlet.monkey_patch()
    app, celery = create_app('config_prod.py')
    

    I'm also using CORS(app) in my app factory.

    I also tried adding this in one of my blueprints:

    @api.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Origin', 'http://localhost:8080')
        response.headers.add('Access-Control-Allow-Headers',
                             'Origin, X-Requested-With, Content-Type, Accept, Authorization')
        response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
        response.headers.add('Access-Control-Allow-Credentials', 'false')
        return response
    

    I'm using nginx as a reverse proxy, and so I tried adding the corresponding configuration I've seen at flask-socketio's docs:

    location /socket.io {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass https://my_backend_host/socket.io;
    }
    

    What's wrong? Thanks!