Reputation:
I've followed a few Medium articles as well as Google's own tutorials and still can't get CORS enabled using flask on this function :(
What code am I missing to enable CORS? I want wildcard of * as I want all services/ domains to be able to access this and other functions.
I've heard GCP does not work well with @app. Why, I am not so sure.
Note I have been successful with testing outputs directly on my browser's url bar as well as Triggering a JSON test within GCP itself.
My intended use is for GET requests only.
from flask import Flask
import re
def hello_method(request):
from flask import abort
if request.method == 'GET':
headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Max-Age': '3600'
}
request_json = request.get_json()
pattern = re.compile("([0-9]+(\.[0-9]+)?)")
if request.args and 'x' and 'y' in request.args:
x_str = request.args.get('x')
y_str = request.args.get('y')
if not (pattern.match(x_str)):
rtn = "{\"error\":true,\"string\":" + "NaN" + "*" + y_str + "=" + "NaN" + ",\"answer\":" + "NaN" +"}"
return (rtn, 204, headers)
if not (pattern.match(y_str)):
rtn = "{\"error\":true,\"string\":" + x_str + "*" + "NaN" + "=" + "NaN" + ",\"answer\":" + "NaN" +"}"
return (rtn, 204, headers)
x = float(x_str)
y = float(y_str)
print("Args X: " + str(x))
print("Args Y: " + str(y))
ans = x * y
print("Args Answer: " + str(ans))
rtn = "{\"error\":false,\"string\":" + str(x) + "*" + str(y) + "=" + str(ans) + ",\"answer\":" + str(ans) +"}"
return (rtn, 204, headers)
elif request_json and 'x' and 'y' in request_json:
x_str = request.args.get('x')
y_str = request.args.get('y')
if not (pattern.match(x_str)):
rtn = "{\"error\":true,\"string\":" + "NaN" + "*" + y_str + "=" + "NaN" + ",\"answer\":" + "NaN" +"}"
return (rtn, 204, headers)
if not (pattern.match(y_str)):
rtn = "{\"error\":true,\"string\":" + x_str + "*" + "NaN" + "=" + "NaN" + ",\"answer\":" + "NaN" +"}"
return (rtn, 204, headers)
print("JSON: ", request_json)
x = float(request_json['x'])
y = float(request_json['y'])
print("JSON X: ", str(x))
print("JSON Y: ", str(y))
ans = x * y
print("JSON Answer 2: " + str(ans))
rtn = "{\"error\":false,\"string\":" + str(x) + "*" + str(y) + "=" + str(ans) + ",\"answer\":" + str(ans) +"}"
return (rtn, 204, headers)
else:
return f"Please pass 2 variables x and y as http"
elif request.method == 'PUT':
return abort(403)
else:
return abort(405)
I seem to be aware of the theory of CORS but my practice isn't yet strong enough and GCP seemingly works with flask-cors differently.
Upvotes: 1
Views: 780
Reputation: 2002
First, don't use Flask. Each function is intended to be a single action and Cloud Functions is already responsible of request routing and the framework handling.
As for the CORS issue there are examples available in the Cloud Functions documentation on how to handle CORS.
In the updated code you're denying the PUT requests and returning the CORS headers on GET method instead of in OPTIONS method. This is not what the documentation linked above does, please check it carefully. The schema of the Cloud Function should be like:
def the_function(request):
# Return CORS headers on OPTIONS request.
if request.method == 'OPTIONS':
headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Max-Age': '3600'
}
return ('', 204, headers)
# If the request is GET then handle it normally
if request.method == 'GET':
x = request.args('x')
y = request.args('x')
result = int(x) * int(y)
headers = {
'Access-Control-Allow-Origin': '*'
}
return (result, 200, headers)
else:
# If the request is not GET or OPTIONS, deny.
return '', 400
I understand that you only want to allow GET requests to the function. However, the OPTIONS HTTP method must be allowed for CORS to work properly. When a webpage requests content to another domain the browser might send a preflight request to the target domain (Cloud Function in this case) asking whether the actual GET/POST/etc.. request will be allowed. In order to accomplish this an OPTIONS request is sent to the server and the server must respond acknowledging the allowed HTTP methods. Therefore, for the function to work as expected it must:
Access-Control-Allow-XXX
headers on OPTIONS method.Upvotes: 1