Method PUT is not allowed by Access-Control-Allow-Methods in preflight response FLASK CORS

11,208

Alright I fixed this. Apparently according to the docs I have to specify "Content-Type" on the cross origin requests. Like so:

@cross_origin(allow_headers=['Content-Type'])

Don't be fooled by the default of allow all. You need to specify this apparently.

I have to remove unnecessary headers such as Accept and Access-Control-Allow-Origin. Updating my axios like so:

axios({
    method: 'PUT',
    url: url,
    timeout: 3000,
    data: data,
    headers: {
        "Content-Type": "application/json",
    },
});

BONUS:

I ran into a problem if my api calls returned a non 200 response with preflight request, the response body becomes null. I just added these lines of code on my main application. I needed the body for the details of the error is there.

@app.after_request
def set_cors_header(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    return response
Share:
11,208
Franrey Saycon
Author by

Franrey Saycon

I engineer full-stack web d/apps and blog about it. I’m an experienced technical team lead and able to drive product and project management in my heavy experience wearing many hats in startups. I’m also a public speaker and tech community leader. I contribute to open source and help fellow developers as much as I can. Don't be shy to reach out in twitter! Founder / President @ reactjs.org.ph || Frontend Dev @ Psychedelics NFT || Senior Dev @ Telus AI

Updated on June 04, 2022

Comments

  • Franrey Saycon
    Franrey Saycon almost 2 years

    GETs are working right. I can't seem to make PUT work and I fear POST is not working as well.

    Kept on having the error

    Access to XMLHttpRequest at '<...>' from origin 'https://localhost:3000' has been blocked by CORS policy: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.
    

    I have a local webapp that calls on an external api which means CORS will be one of the hurdles I should tackle.

    Here's my flask code.

    @blueprint.route('/profiles/<oi_id>', methods=['POST'])
    @cross_origin(send_wildcard=True, methods=['POST', 'OPTIONS'])
    def create_checkin_profile(oi_id):
        return jsonify(cph.create_owner_profile_info(oi_id, json.loads(request.data)))
    
    
    @blueprint.route('/profiles/<oi_id>', methods=['PUT'])
    @cross_origin(send_wildcard=True, methods=['PUT', 'OPTIONS'])
    def edit_checkin_profile(oi_id):
        return jsonify(cph.edit_owner_profile_info(oi_id, json.loads(request.data)))
    

    It's quite confusing since I'm pretty sure I allowed PUT. I'm using axios for this on a react app. Here's my call-api function.

    axios({
          method: 'PUT',
          url: url,
          timeout: 3000,
          data: data,
          headers: {
            "Access-Control-Allow-Origin": "*",
            "Content-Type": "application/json",
            Accept: "application/json",
          },
        });
    
    • Satyaki
      Satyaki over 5 years
      From React side, it appears to me your implementations are correct, please check how to handle cors in flask.
    • Franrey Saycon
      Franrey Saycon over 5 years
      I just used Flask-Cors. @cross_origin() decorator in which it should handle the CORS requests nicely. That's why I'm confused why it doesn't work.
    • Satyaki
      Satyaki over 5 years
      I'm not a python guy. So can't confirm but this might help you : stackoverflow.com/questions/39550920/…