【问题标题】:Google Cloud Function: Python and CORS谷歌云函数:Python 和 CORS
【发布时间】:2020-11-21 20:04:14
【问题描述】:

谁能告诉我我做错了什么,我一直在阅读 Google Cloud Functions 文档,但对我来说没有意义...

这是文档的链接: https://cloud.google.com/functions/docs/writing/http#functions_http_cors-python

代码如下:

import flask, json, logging, os, requests
from requests.exceptions import HTTPError

def get_accesstoken():
  try:
    headers   = {'Content-type': 'application/json', 'Accept': 'text/plain'}
    authUrl   = f"{os.environ.get('AUTH_BASE_URI')}{os.environ.get('AUTH_ENDPOINT')}"
    payload   = {'client_id': os.environ.get("CLIENT_ID"), 'client_secret': os.environ.get("CLIENT_SECRET"), 'grant_type': os.environ.get("GRANT_TYPE")}
    resp      = requests.post(authUrl, data=json.dumps(payload), headers=headers)

    return resp.json()

  except HTTPError as http_err:
    print(f'HTTP error occurred: {http_err}')
    return http_err

  except Exception as err:
    print(f'Other error occurred: {err}')
    return err


def addrecord(request): ## <--- this is the entry cloud function
  """HTTP Cloud Function
  Add records to ANY MC DataExtension
  
  Args:
        request (flask.Request): The request object.
        <http://flask.pocoo.org/docs/1.0/api/#flask.Request>
    ----------------------------------------------------------------------------
    data        = request.get_json().get('data', [{}]) // JSON array of objects
    dataId      = request.get_json().get('dataId', None) // string
  """

  request_json  = request.get_json(silent=True)
  token         = get_accesstoken()
  payload       = request_json["data"]
  dextUrl       = f"{os.environ.get('REST_BASE_URI')}{os.environ.get('REST_DE_ENDPOINT')}{request_json['dataExtId']}/rowset"

  # Set CORS headers for the preflight request
  if request.method == 'OPTIONS':
      # Allows GET & POST 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, POST',
          'Access-Control-Allow-Headers': 'Content-Type',
          'Access-Control-Max-Age': '3600'
      }

      return ('', 204, headers)

  headers       = {
    'Content-type': 'application/json',
    'Authorization': 'Bearer '+token["access_token"],
    'Access-Control-Allow-Origin': '*'
  }

  resp          = requests.post(dextUrl, data=json.dumps(payload), headers=headers)
  return(resp.raise_for_status(), 200, headers)

当我尝试从前端表单发送 POST 请求时 - 我收到以下错误:

Access to XMLHttpRequest at 'https://xxxxxxxxxx.cloudfunctions.net/addrecord' from origin 'https://mywebsite.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

老实说,我不明白我错过了什么/做错了什么......我也觉得我可能把事情复杂化了。

为了完成这个循环,这里是 POST 请求的 JS 代码:

let postData = {...};

$.ajax({
        url: 'https://xxxxxxxxxx.cloudfunctions.net/addrecord',
        type: 'post',
        crossDomain: true,
        contentType: 'application/json',
        dataType: 'json',
        data: JSON.stringify(postData),
        success: function (data) {
          console.info(data);
        },
        error: function (data) {
          console.log(data)
        }
      });

【问题讨论】:

  • 为什么我的帖子得到了-1?

标签: python python-3.x request google-cloud-functions cors


【解决方案1】:

你没有 else 设置标题的 if 块。

因此,您的第二个 headers = 块始终是正在设置的块。第二个分配不是将这些标头附加到数据中,而是完全重新分配变量。所以你没有在那里得到访问源头。

测试它以验证的方法是在第二次分配之后放置一个print(headers) 以查看发生了什么。

编辑:在 OPTIONS 案例的 if 块中缺少返回。

【讨论】:

  • 感谢您的快速回复 - 我真的很感激... ...在 GCP Cloud Function 文档中没有 ELSE 块/语句,这就是为什么我没有它我的代码...
  • 请注意,在文档中,在 if 块中,在 OPTIONS 块的访问控制标头之后有一个返回。您的代码没有返回值。
  • 啊哈——确实如此……我想我知道我需要做什么了……
  • 太棒了!你能接受答案,以便以后更容易搜索吗?谢谢!
【解决方案2】:

感谢@Gabe Weiss --

我意识到我需要做三件事......

首先,我在if request.method == 'OPTIONS': 语句的末尾添加了return ('', 204, headers)

其次,我将请求调用移至设置标头后。 最后,我返回了响应

【讨论】:

    猜你喜欢
    • 2021-01-12
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 2021-05-09
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    相关资源
    最近更新 更多