3

I'm making API calls from angular to flask. In flask, I'm getting [OPTIONS] instead of [POST]. If I make the same API call twice then the flask will recognize it as [POST] method.

this is the flask code:

import numpy as np
import pickle

from flask import Flask, request, redirect
from flask.json import jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS

app = Flask(__name__)
cors = CORS(app, resources={r"*": {"origins": "*"}})

app.secret_key = "Secret Key"
model = pickle.load(open('model.pkl', 'rb'))

#API Calls
@app.route('/',methods=["GET"])
def index():
    if request.method == "GET":
        return jsonify(data="Hello World")

@app.route('/login',methods=['POST'])
def login():
    if request.method == 'POST':
        data = request.get_json()
        return jsonify(data),200

@app.route('/register',methods=["POST"])
def register():
    if request.method == 'POST':
        data = request.get_json()
        email = data["email"]
        username = data["displayName"]
        password = data["password"]
        res = {
            "result" : "success"
        }
        return jsonify(res),200

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

and this the the API service in Angular:

export class ApiService {
  constructor(private http: HttpClient) {}

  getHeaders(method: string) {
    const token = localStorage.getItem("token");
    const headers: any = {};

    if (method === "post") {
      headers["Content-type"] = "application/json";
    }  

    return {
      headers: new HttpHeaders(headers),
    };
  }

  get(url: string) {
    const headers = this.getHeaders("get");
    return this.http.get(`${environment.apiUrl}${url}`, headers).toPromise();
  }

  post(url: string, payload: Object) {
    const headers = this.getHeaders("post");
    return this.http
      .post(`${environment.apiUrl}${url}`, payload, headers)
      .toPromise();
  }
}

and this is the method I'm calling when I click on the register button:

constructor(private api: ApiService, private router: Router) {}

  ngOnInit(): void {}

  async register(email: string,password: string,passwordCheck: string, displayName: string) 
  {
    const newUser = {
      email,
      password,
      passwordCheck,
      displayName,
    };
    try {
      const result = await this.api.post("/register", newUser);
      console.log(result)
      this.router.navigate(["/login"]);
    } catch (err) {
      console.log(err);
    }
  }

Terminal output in flask:

127.0.0.1 - - [17/Jun/2021 09:48:14] "OPTIONS /register HTTP/1.1" 200 -
127.0.0.1 - - [17/Jun/2021 09:48:19] "POST /register HTTP/1.1" 200 -

Network tab in Inspect: register

Thanks.

  • 1
    https://stackoverflow.com/questions/29954037/why-is-an-options-request-sent-and-can-i-disable-it – Brian Destura Jun 17 '21 at 04:27
  • @bdbd So how can i send JSON data, if we cant use content-type=application/JSON. I seem to encounter this problem only in flask. In express i use cors and the same headers but it works fine. – Ratandeep Arunkumar Jun 17 '21 at 04:39

1 Answers1

2

Hi I was having the same prblem. And the thing is that browsers will send a "preflight" request with the OPTION method. here's more info https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS. if this is giving you CORS problem in the client side I solved it catching the request and verifing if the method was OPTIONS and adding some headers to the response for the OPTION request:

from flask import Flask, request, Response
from flask_cors import CORS


app = Flask(__name__)
CORS(app)


@app.before_request
def handle_preflight():
    if request.method == "OPTIONS":
        res = Response()
        res.headers['X-Content-Type-Options'] = '*'
        return res
        
    
  • You shouldnt have problems if you user app(CORS). But if you do that might help. Another thing that I would try is deleting all the __pychache__ files. I dont know why but one time I was having this issue and after i deleted those files (Becacuse someone told me so) the app run correctly just using app(CORS) – Jose Francisco Cheble Mar 28 '23 at 15:54