Search code examples
flaskcorsflask-cors

How to fix: "Origin <localhost> is not allowed by Access-Control-Allow-Origin." -- with flask_cors


I have set up a server with flask CORS and had it working for sending data to a React web app that I built, but when I went to test the POST method it stoped working and now it is broken for sending and receiving. The error log in the console of the web app is: "Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. Fetch API cannot load http://127.0.0.1:5000/ due to access control checks. "

I ran into this issue earlier and added flask_cors and it worked for a while. Here is my server code:

from flask_cors import CORS, cross_origin

app = FlaskAPI(__name__)
app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy dog'
app.config['CORS_HEADERS'] = 'Content-Type'

cors = CORS(app, resources={r"/": {"origins": "http://localhost:port"}})
# Also fails with this variation
# cors = CORS(app, resources={r"/api/*": {"origins": "*"}})

@app.route("/", methods=['GET', 'POST'])
@cross_origin(origin='localhost',headers=['Content- Type','Authorization'])
# Also fails with these variations
# @cross_origin(origin='http://127.0.0.1:5000/',headers=['Content- Type','Authorization'])
# @cross_origin(origin='http://localhost:3000',headers=['Content- Type','Authorization'])  
def job_api():
    with app.app_context():
        job_data = get_job_data()
        json_data = jsonify(eqtls=[job.data for job in job_data])
        return json_data

if __name__ == "__main__":
    app.run(debug=True)

Here is my client code:

  componentDidMount() {
        fetch('http://127.0.0.1:5000/')
        .then(res => res.json())
        .then((data) => {
          this.setState({ job_data: data.eqtls })
        })
        .catch(console.log)
  }

Solution

  • You need to enable CORS policy on your API, so it can accept requests from across different hosts.

    Just do a google Flask cors, and make sure you are Accepting '*' or specifically your URL.

    If you accept cors though you should be able to accept all CORS and then make your API robust enough so that no nasty data can be requested

    Try:

    from flask_cors import CORS, cross_origin
    
    app = FlaskAPI(__name__)
    app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy dog'
    app.config['CORS_HEADERS'] = 'Content-Type'
    
    
    @app.route("/", methods=['GET', 'POST'])
    @cross_origin()
    def job_api():
        with app.app_context():
            job_data = get_job_data()
            json_data = jsonify(eqtls=[job.data for job in job_data])
            return json_data
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    I read the documenttation, and can just add @cross_origin() as a simple decorator: https://flask-cors.readthedocs.io/en/latest/#route-specific-cors-via-decorator