7

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

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

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

4

6 回答 6

10

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

然后,在您的云功能后端,您还必须处理预检请求()。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 网关没有以适当的方式管理预检请求的缺点会导致两次运行云功能的惩罚。但是您的第二个请求应该总是非常快,因为第一个请求充当热身请求。

于 2021-01-15T14:46:26.947 回答
5

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

参考

于 2020-10-09T17:21:24.437 回答
3

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

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

允许全部

访问控制来源:'*'

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

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

如果您没有实现负载均衡器,您可以按照本教程来实现一个新的Google API Gateway、负载均衡器和内容分发网络

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

于 2020-11-17T21:51:10.473 回答
3
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 .

于 2021-02-26T06:17:49.700 回答
3

解决方案

这是解决方案。正如 user14982714 所说。oepnapi.yaml在顶级文件中添加主机和 x-google-endpoints :

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

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

在此处输入图像描述

出于隐私考虑,我覆盖了端点名称的开头,但是,您的端点名称也应该以.cloud.goog. 如果您还没有部署配置,请在没有 x-google-endpoints 和主机的情况下部署它,然后更新它以包含两者。(要更新您的配置,请转到 API Gateway -> Your API -> Gateways Tab -> Your Gateway -> Edit-> Change API Config -> Create New)

解释

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

在此处输入图像描述

所以知道了这一点,我尝试添加allowCors: truex-google-endpoints中提琴。有效。我希望这可以帮助那里的人。

于 2021-05-24T20:35:08.680 回答
1

我与其他 API 有类似的问题,所以我不确定在你的情况下同样的问题,但你可以尝试 - 在获取数据时的反应应用程序中,假设你可以尝试使用 axios

    axios.post('http://localhost:3003/signup',this.data,{headers:{'Access-Control- 
    Allow-Origin':'*','Content-Type': 'application/json'}})

在后端 - 试试这个 -

  let cors=require('./cors')
  app.options('*', cors());

它适用于我的情况,希望对您有所帮助。

于 2020-10-09T14:23:48.007 回答