use*_*308 2 python xmlhttprequest google-cloud-platform google-cloud-functions
因为过去几周我的浏览器控制台中出现了一些意外的 CORS 错误,所以我在 Google Cloud Functions 中设置了一个超级简单的 Python 脚本,其中包含一个函数:
def prepData(request):
if request.method == 'OPTIONS':
headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Max-Age': '3600'
}
return ('', 204, headers)
headers = {
'Access-Control-Allow-Origin': '*'
}
return ("", 200, headers)
Run Code Online (Sandbox Code Playgroud)
它看起来与 Google 在其文档页面上提供的功能非常相似,但有一个主要区别:我使用的是 POST 而不是 GET。
调用该函数时,我Function execution took 13 ms, finished with status code: 200在大约 50% 的情况下看到成功消息 ( ),Function execution took 11 ms, finished with status: 'connection error'在所有其他情况下看到连接错误 ( )。每当我在 GCF 中遇到连接错误时,Chrome 的控制台都会记录一个错误:No 'Access-Control-Allow-Origin' header is present on the requested resource.
我目前正在考虑三个可能的原因:
问题的原因是什么,我该如何解决?
下面是调用 Python 脚本的 JS 代码:
const xhr = new XMLHttpRequest();
xhr.open("POST", "[URL]");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(stringified_serialized_data);
Run Code Online (Sandbox Code Playgroud)
20 年 4 月 2 日编辑:
我发现了一种不触发错误的方法:在两个 return 语句之间添加一些代码。我还没有弄清楚需要什么样的代码,但d = request.get_json()似乎已经足够了。新代码如下所示:
def prepData(request):
if request.method == 'OPTIONS':
headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Max-Age': '3600'
}
return ('', 204, headers)
d = request.get_json() #THIS LINE IS NEW
headers = {
'Access-Control-Allow-Origin': '*'
}
return ("", 200, headers)
Run Code Online (Sandbox Code Playgroud)
更新
进一步挖掘后,我们意识到问题实际上是 Google Cloud Function 服务中的一个错误。此错误特别影响使用 Python 运行时的云函数。如果这些函数收到正文大于约 10 KB 的 HTTP POST 请求,它们将引发连接错误(并返回代码 500)。有趣的是,这不会在每个具有此类特征的请求中发生,而是在大多数请求中发生。
谷歌支持服务被告知这个问题,他们承认了这个错误。他们在问题跟踪器中创建了一个公共问题,应根据解决方案的进度更新附加信息。在撰写本文时,该问题已标记为“新”。
解决方法:正如@Timon 所建议的,似乎调用request.get_json()该函数似乎可以解决带有 JSON 正文的请求的问题。如果您的请求正文使用不同的格式,这将不起作用。
旧答案
我刚刚使用您提供的完全相同的代码设置了一个干净的 GC 函数,并且它运行完美。我可以通过浏览器发出请求(使用您的 JS 代码)并且它们永远不会失败。
这给我们留下了两个选择:
对于选项 1,请检查:
对于选项 2,请检查: