【问题标题】:Google Cloud Functions enable CORS?Google Cloud Functions 启用 CORS?
【发布时间】:2016-06-12 03:36:14
【问题描述】:

我刚刚完成了 Hello World Google Cloud Functions 教程并收到了以下响应标头:

Connection → keep-alive
Content-Length → 14
Content-Type → text/plain; charset=utf-8
Date → Mon, 29 Feb 2016 07:02:37 GMT
Execution-Id → XbT-WC9lXKL-0
Server → nginx

如何添加 CORS 标头以便能够从我的网站调用我的函数?

【问题讨论】:

    标签: google-cloud-platform cors google-cloud-functions


    【解决方案1】:

    我是 Google Cloud Functions 的产品经理。感谢您的提问,这是一个很受欢迎的请求。

    我们目前还没有任何要宣布的内容,但我们知道需要对 Cloud Functions 的 HTTP 调用功能进行几项增强,我们将在这方面和许多其他领域推出改进未来的迭代。

    更新:

    我们改进了您在 Cloud Functions 中处理 HTTP 的方式。您现在拥有对 HTTP 请求/响应对象的完全访问权限,因此您可以设置适当的 CORS 标头并响应飞行前 OPTIONS 请求 (https://cloud.google.com/functions/docs/writing/http)

    【讨论】:

    • 提供的链接 (cloud.google.com/functions/docs/writing/http) 没有提及任何关于 cors 的内容。有没有官方文档可以看?我希望会有一个 UI 来更改这些设置(法律),但似乎没有。
    • beta python 环境是否支持CORS?
    • Python 环境使用 Flask 作为其 Web 框架,因此您应该能够使用标准 Flask 语义手动设置 CORS 标头。我们正在逐渐在缺少的地方添加 python 示例,这就是其中之一。在此处讨论的 Flask 中设置标题:stackoverflow.com/questions/29464276/…
    • 这里的文档相当混乱。 ttps://firebase.google.com/docs/functions/http-events 。和快递有什么关系?
    【解决方案2】:

    您可以使用 CORS express 中间件。

    package.json

    npm install express --save
    npm install cors --save
    

    index.js

    'use strict';
    
    const functions = require('firebase-functions');
    const express = require('express');
    const cors = require('cors')({origin: true});
    const app = express();
    
    app.use(cors);
    app.get('*', (req, res) => {
        res.send(`Hello, world`);
    });
    
    exports.hello = functions.https.onRequest(app);
    

    【讨论】:

      【解决方案3】:

      我们开始:

      exports.helloWorld = function helloWorld(req, res) {  
        res.set('Access-Control-Allow-Origin', "*")
        res.set('Access-Control-Allow-Methods', 'GET, POST');
      
        if (req.method === "OPTIONS") {
          // stop preflight requests here
          res.status(204).send('');
          return;
        }
      
        // handle full requests
        res.status(200).send('weeee!);
      };
      

      然后你可以像往常一样使用 jquery/whatever 它:

      $.get(myUrl, (r) => console.log(r))
      

      【讨论】:

      • 我已经尝试了上述实现,但我收到:请求标头字段 X-Requested-With 在预检响应中被 Access-Control-Allow-Headers 不允许。有什么建议吗?
      • 在发送响应之前尝试添加 res.set('Access-Control-Allow-Headers', 'Content Type', 'X-Requested-Width', '...')
      • It does not have HTTP ok status.
      • 如何在 python 运行时做同样的事情?
      【解决方案4】:

      我刚刚创建了webfunc。它是一个轻量级 HTTP 服务器,支持 CORS 以及 Google Cloud Functions 的路由。示例:

      const { serveHttp, app } = require('webfunc')
      
      exports.yourapp = serveHttp([
        app.get('/', (req, res) => res.status(200).send('Hello World')),
        app.get('/users/{userId}', (req, res, params) => res.status(200).send(`Hello user ${params.userId}`)),
        app.get('/users/{userId}/document/{docName}', (req, res, params) => res.status(200).send(`Hello user ${params.userId}. I like your document ${params.docName}`)),
      ])
      

      在您项目的根目录中,只需添加如下所示的 appconfig.json

      {
        "headers": {
          "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS, POST",
          "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
          "Access-Control-Allow-Origin": "*",
          "Access-Control-Max-Age": "1296000"
        }
      }
      

      希望这会有所帮助。

      【讨论】:

        【解决方案5】:

        在python环境下,可以使用flask request object来管理CORS请求。

        def cors_enabled_function(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)
        

        请参阅gcloud docs 了解更多信息。

        【讨论】:

          【解决方案6】:

          您必须在所有函数中启用 CORS,例如 hello 函数:

          index.js

          const cors = require('cors')();
          
          // My Hello Function
          function hello(req, res) {
            res.status(200)
              .send('Hello, Functions');
          };
          
          // CORS and Cloud Functions export
          exports.hello = (req, res) => {
            cors(req, res, () => {
              hello(req, res);
            });
          }
          

          不要忘记 package.json

          package.json

          {
            "name": "function-hello",
            "version": "0.1.0",
            "private": true,
            "dependencies": {
              "cors": "^2.8.5"
            }
          }
          

          【讨论】:

            【解决方案7】:

            您需要发送'OPTIONS' 响应,方法是设置其标头如下:

            if (req.method === 'OPTIONS') {
              res.set('Access-Control-Allow-Methods', '*');
              res.set('Access-Control-Allow-Headers', '*');
              res.status(204).send('');
            }
            

            运行时:NodeJS 10

            【讨论】:

            • 这是一个预检请求处理程序。有关更深入的解释,请参阅the docs
            【解决方案8】:

            如果您尝试了accepted answer,但遇到了预检错误,docs 提供了以多种语言处理它的示例,caveat 仅适用于公共功能,即使用--allow-unauthenticated 部署:

            exports.corsEnabledFunction = (req, res) => {
              res.set("Access-Control-Allow-Origin", "*");
            
              if (req.method === "OPTIONS") {
                /* handle preflight OPTIONS request */
                
                res.set("Access-Control-Allow-Methods", "GET, POST");
                res.set("Access-Control-Allow-Headers", "Content-Type");
            
                // cache preflight response for 3600 sec
                res.set("Access-Control-Max-Age", "3600");
                
                return res.sendStatus(204);
              }
            
              // handle the main request
              res.send("main response");
            };
            

            【讨论】:

            • 注意:原始答案后 6 个月:已接受的答案已被编辑以处理 CORS,但我将把它留给后代,因为它看起来更清晰。
            【解决方案9】:

            从此处应用您最喜欢的答案后,如果您仍然收到此错误,请检查您的云函数中是否存在未捕获的错误。这可能会导致浏览器收到 CORS 错误,即使您的错误与 CORS 无关

            【讨论】:

              猜你喜欢
              • 2017-08-02
              • 2017-02-19
              • 1970-01-01
              • 2020-06-17
              • 2021-03-25
              • 2016-05-26
              • 2021-12-26
              • 1970-01-01
              • 2020-11-03
              相关资源
              最近更新 更多