尝试从新的 Google Cloud API Gateway 获取时出现 CORS 错误

Ele*_*ark 7 cors reactjs google-cloud-platform google-cloud-functions google-cloud-api-gateway

我正在测试新的 API 网关,以保护我的 React 应用程序的云功能。到目前为止,这个过程比之前的替代方案要好得多,但是当我尝试从我的 React 应用程序访问我的 API 网关时,我目前遇到了 CORS 错误。我在我的 Cloud Function 中正确设置了 CORS 标头,但我不知道在 API Gateway 端点上执行相同操作的方法。我正在使用 Postman 测试对网关端点的请求,并且一切正常,所以这正是我从 React 应用程序请求时。

错误:“从源“https://example.netlify.app”获取“https://my-gateway-a12bcd345e67f89g0h.uc.gateway.dev/hello?key=example”的访问权限已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用了 CORS 的资源。”

希望对这个问题有所了解。谢谢!

Ant*_*tte 12

解决方案

这是解决方案。正如用户14982714所说。将主机和 x-google-endpoints 添加到您的oepnapi.yaml文件的顶层:

host: my-cool-api.endpoints.my-project-id.cloud.goog
x-google-endpoints:
- name: my-cool-api.endpoints.my-project-id.cloud.goog
  allowCors: True
Run Code Online (Sandbox Code Playgroud)

但是,请务必替换my-cool-api.endpoints.my-project-id.cloud.goog为您的 API 托管服务 URL。这可以在您的谷歌云控制台的 API Gateway API 下找到:

在此输入图像描述

为了保护隐私,我覆盖了端点名称的开头,但是,您的端点名称也应该以.cloud.goog. 如果您尚未部署配置,请在不包含 x-google-endpoints 和主机的情况下部署它,然后更新它以包含两者。(要更新您的配置,请转至 API 网关 -> 您的 API -> 网关选项卡 -> 您的网关 -> 编辑 -> 更改 API 配置 -> 新建)

解释

现在解释一下为什么这可以与 Google Cloud API Gateway 配合使用。API 网关在底层使用端点。大多数人不知道情况确实如此,但是,在放弃 API 网关并返回到端点之后,我注意到我的 API 网关列在端点服务下。它们不会显示在 UI 中,但使用 gcloud CLI 运行此命令,gcloud endpoints services list您应该会看到 API 网关。疯狂的!但谷歌经常这样做。

在此输入图像描述

因此,知道这一点后,我尝试添加allowCors: truex-google-endpoints和 中提琴中。有效。我希望这对那里的人有帮助。

  • 为此,您需要支持 CORS 的云端点。然而,最初的问题是关于使用云函数作为后端。 (2认同)
  • 这确实有效。如果像我一样,您的 API 网关位于负载均衡器后面以支持自定义域名,则您应该使用原始的“cloud.goog”服务名称,如命令“gcloud endpoints services list”中所示,而不是自定义域名。 (2认同)

Neb*_*tic 9

这尚不受支持,但是,有一个临时解决方法可以使其正常工作。您应该添加optionsopenapi.yaml. 此外,getoptions操作都应该指向同一个云函数,因为该options请求随后充当了云函数的预热请求。就延迟而言,这是最有效的设置。这是一个简化的示例:

paths:
  /helloworld:
    get:
      operationId: getHelloWorld
      x-google-backend:
        address: $CLOUD_FUNCTION_ADDRESS
      responses:
        '200':
          description: A successful response
    options:
      operationId: corsHelloWorld
      x-google-backend:
        address: $CLOUD_FUNCTION_ADDRESS
      responses:
        '200':
          description: A successful response
Run Code Online (Sandbox Code Playgroud)

然后,在您的云函数后端,您还必须处理预检请求 ( source )。Google 文档还提供了一个带有 authentication的示例,其中包含一些额外的标头。这是一个没有身份验证的示例:

def cors_enabled_function(request):
    # For more information about CORS and CORS preflight requests, see
    # https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
    # for more information.

    # 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)
Run Code Online (Sandbox Code Playgroud)

注意:API 网关没有以适当的方式管理预检请求的缺点会导致两次运行云功能的惩罚。但是您的第二个请求应该总是非常快,因为第一个请求充当预热请求。


Ele*_*ark 5

事实证明 API Gateway 目前不支持 CORS。

参考