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

IT技术 reactjs google-cloud-platform google-cloud-functions cors google-cloud-api-gateway
2021-04-27 13:30:39

我正在测试新的 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 的资源。”

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

4个回答

这尚不受支持,但是,有一个临时解决方法可以使其正常工作。您应该添加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

然后,在您的云函数后端,您还必须处理预检请求 ( 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)

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

事实证明,API Gateway 目前没有 CORS 支持。

参考

我遇到了同样的问题并使用负载均衡器解决了它(最初用于向我的 API 网关添加自定义域)。我使用负载平衡器将缺少的标头添加到响应中。

您只需要添加“Access-Control-Origin”标头:

允许全部

访问控制来源:'*'

允许特定来源 Access-Control-Allow-Origin:http : //example.com : 8080

您可以在此处找到GCP-创建自定义标头的说明

如果您没有实现负载均衡器,您可以按照本教程实现一个新的Google API Gateway、Load Balancer 和 Content Delivery Network

您可以在https://www.w3.org/wiki/CORS_Enabled找到有关 CORS 的更多信息

swagger: "2.0"
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

注意:主机和名称应具有相同的 API 端点名称

在您的配置文件中配置这些行可以为 API GATEWAY 启用 CORS

[参考][1]

[1]:https://cloud.google.com/endpoints/docs/openapi/support-cors#:~:text=CORS%20(Cross%2Dorigin%20resource%20sharing,would%20prevent%20cross%2Dorigin%20requests .