我目前正在学习如何使用Firebase的新云函数,我遇到的问题是我无法访问我通过AJAX请求编写的函数。我得到了“No 'Access-Control-Allow-Origin'”错误。下面是我写的函数示例:

exports.test = functions.https.onRequest((request, response) => {
  response.status(500).send({test: 'Testing functions'});
})

函数位于这个url中: https://us-central1-fba-shipper-140ae.cloudfunctions.net/test

Firebase文档建议在函数中添加CORS中间件,我尝试过,但对我不起作用:https://firebase.google.com/docs/functions/http-events

我是这样做的:

var cors = require('cors');    

exports.test = functions.https.onRequest((request, response) => {
   cors(request, response, () => {
     response.status(500).send({test: 'Testing functions'});
   })
})

我做错了什么?如果你能帮我,我会很感激。

更新:

道格·史蒂文森的回答很有帮助。添加({origin: true})修复了这个问题,我还必须将response.status(500)更改为response.status(200),这是我一开始完全错过的。


当前回答

对于它的价值,我有同样的问题,当传递应用程序到onRequest。我意识到问题在于firebase函数的请求url上的末尾斜杠。Express正在寻找'/',但我在函数[project-id].cloudfunctions.net/[function-name]上没有后面的斜杠。CORS的错误是假阴性。当我添加后面的斜杠时,我得到了我所期待的响应。

其他回答

如果你在本地测试firebase应用程序,那么你需要将函数指向localhost而不是cloud。默认情况下,firebase服务或firebase模拟器:当你在你的web应用程序上使用它时,开始将函数指向服务器而不是localhost。

在firebase初始化脚本后的html头中添加以下脚本:

 <script>
      firebase.functions().useFunctionsEmulator('http://localhost:5001')
 </script> 

确保在将代码部署到服务器时删除此代码段。

Go into your Google Cloud Functions. You may have not seen this platform before, but it's how you'll fix this Firebase problem. Find the Firebase function you're searching for and click on the name. If this page is blank, you may need to search for Cloud Functions and select the page from the results. Find your function, click on the name. Go to the permissions tab. Click Add (to add user). Under new principles, type 'allUsers' -- it should autocomplete before you finish typing. Under select a role, search for Cloud Functions, then choose Invoker. Save. Wait a couple minutes.

这应该能解决问题。如果没有,就这样做,并在你的函数代码中添加一个CORS解决方案,比如:

  exports.sendMail = functions.https.onRequest((request, response) => {
  response.set("Access-Control-Allow-Origin", "*");
  response.send("Hello from Firebase!");
});

我对安德烈自己的问题有一些补充。

看起来你不需要在cors(req, res, cb)函数中调用回调,所以你可以在函数的顶部调用cors模块,而不需要在回调中嵌入你的所有代码。如果您想随后实现cors,这将更快。

exports.exampleFunction = functions.https.onRequest((request, response) => {
    cors(request, response, () => {});
    return response.send("Hello from Firebase!");
});

不要忘记初始化cors,就像开头提到的那样:

const cors = require('cors')({origin: true});

更新:任何需要时间的响应函数都有可能在此实现中出现CORS错误,因为它没有适当的async/await。不要在返回静态数据的快速原型端点之外使用。

如果没有捕获函数中的错误,就会发生cors错误。我的建议是在corsHandler中实现try catch

const corsHandler = (request, response, handler) => {
    cors({ origin: true })(request, response, async () => {
        try {
            await handler();
        }
        catch (e) {
            functions.logger.error('Error: ' + e);
            response.statusCode = 500;
            response.send({
                'status': 'ERROR' //Optional: customize your error message here
            });
        }
    });
};

用法:

exports.helloWorld = functions.https.onRequest((request, response) => {
    corsHandler(request, response, () => {
        functions.logger.info("Hello logs!");
        response.send({
            "data": "Hello from Firebase!"
        });
    });
});

感谢stackoverflow的用户:Hoang Trinh, Yayo Arellano和Doug Stevenson

对于它的价值,我有同样的问题,当传递应用程序到onRequest。我意识到问题在于firebase函数的请求url上的末尾斜杠。Express正在寻找'/',但我在函数[project-id].cloudfunctions.net/[function-name]上没有后面的斜杠。CORS的错误是假阴性。当我添加后面的斜杠时,我得到了我所期待的响应。