基于 Python 的 Google Cloud Functions 持续存在 CORS 问题,即使使用 Docs 示例也是如此

Persistent CORS issues with Python-based Google Cloud Functions, even using the Docs example

提问人:Hack-R 提问时间:7/7/2023 最后编辑:Hack-R 更新时间:7/9/2023 访问量:126

问:

CORS 在尝试使用 查询 Cloud Function 时导致我的 Web 应用出现高度持久的错误。我有许多 Node.js 云函数可以与我的 Flutter 应用程序无缝地工作,但在这个 Next.js 应用程序中,我特别需要利用 Python 云函数。axios

我已经尝试了多种方式处理 CORS,但即使我只是从字面上使用 Docs 的示例,我仍然会遇到 CORS 错误。以下是 Cloud Function 代码:

import functions_framework

@functions_framework.http
def myFun(request):
    # Set CORS headers for the preflight request
    if request.method == "OPTIONS":
        # Allows GET requests from any origin with the Content-Type
        # header and caches preflight response for an 3600s
        headers = {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "GET",
            "Access-Control-Allow-Headers": "Content-Type",
            "Access-Control-Max-Age": "3600",
        }

        return ("", 204, headers)

    # Set CORS headers for the main request
    headers = {"Access-Control-Allow-Origin": "*"}

    return ("Hello World!", 200, headers)

这就是我调用函数的方式:

            axios
              .post(
                "https://myurl.cloudfunctions.net/myFun",
                body,
                {
                  headers: {
                    Authorization: `bearer ${token}`,
                    "Content-Type": "application/json",
                  },
                },
              )
              .then((response) => {
                console.log("Raw response: ", response.data);
                const completion = response.data;
                botMessage.content = completion;
                console.log("Clean response: ", completion);
                get().onNewMessage(botMessage);
              })
              .catch((error) => {
                console.error(
                  "Error while calling Cloud Function:",
                  error,
                );
              });

错误:

message: "Network Error", name: "AxiosError", code: "ERR_NETWORK", config: {…}, request: XMLHttpRequest }
app-index.js:33:22
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource

我尝试将文档示例中的“GET”更改为“POST”。

python 平台谷歌云 函数 cors

评论

0赞 John Hanley 7/7/2023
检查您的函数是否返回 HTTP Status 2xx 以外的内容。应用通常不会在出现错误时返回 CORS 标头。浏览器报告 CORS 错误,而不是显示实际的 HTTP 错误。
0赞 Hack-R 7/7/2023
@JohnHanley谢谢。我在浏览器控制台中没有看到正确的状态代码。它有常见的 CORS Blocked 消息和一些很长的、看起来很通用的 axios 错误...... 这是在我将 GET 更改为 POST 之前和之后。Error while calling Cloud Function: Object { stack: "AxiosError@webpack-internal:///(app-client)/./node_modules/axios/lib/core/AxiosError.js:24:19\nhandleError@webpack-internal:///(app-client)/./node_modules/axios/lib/adapters/xhr.js:172:14\n", message: "Network Error", name: "AxiosError", code: "ERR_NETWORK", config: {…}, request: XMLHttpRequest }
0赞 Hack-R 7/7/2023
在 GCP 端,它不显示任何内容。
0赞 John Hanley 7/7/2023
浏览器将阻止显示由于 CORS 导致的错误。您可以使用像 Wireshark 这样的工具,也可以在后端代码中报告 HTTP 状态。为每个 HTTP 请求和响应添加日志记录。关键是记录来自应用的响应。
1赞 Hack-R 7/9/2023
@jub0bs 在我最终得到下面适合我的版本之前,我经历了很多次迭代,但是的,这可能是其中的一部分。我确实有下面。谢谢。Authorization

答:

0赞 Hack-R 7/9/2023 #1

我经历了如此多的迭代才能让它工作,很难跟踪,但关键的最终变化是改变它(这不是在我上面开始的示例中,而是在下面以后的迭代中):

return None  

对此:

return '', 400, headers

和这个

return response_json, 200, {'Content-Type': 'application/json'}

对此:

return response_json, 200, headers

在这个迭代中(它建立在我的问题中上面的 Hello World 版本之上,我开始工作,但随后 - 在使用我真正的 Cloud Function 逻辑进行修改后 - 需要上述更改):

import pandas as pd
import numpy as np
import functions_framework
import json

@functions_framework.http
def myFun(request):
# Set CORS headers for the preflight request
if request.method == 'OPTIONS':
    # Allows POST and GET requests from any origin with the Content-Type
    # header and caches preflight response for 3600 seconds (1 hour)
    headers = {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST, GET',
        'Access-Control-Allow-Headers': 'Content-Type, Authorization',
        'Access-Control-Max-Age': '3600'
    }

    return ('', 204, headers)

# Set CORS headers for the main request
headers = {
    'Access-Control-Allow-Origin': '*'
}

# Read the CSV file with prompt embeddings and completions
df = pd.read_csv('my_file.csv')

# project-specific logic went here

# Check something specific to my project here
if this_data is None:
    return '', 400, headers

# Calculate stuff
stuff = this_data

response_data = {'my_stuff': stuff}
response_json = json.dumps(response_data)
return response_json, 200, headers