我目前正在学习如何使用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),这是我一开始完全错过的。


当前回答

如果没有捕获函数中的错误,就会发生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

其他回答

如果有像我这样的人:如果你想在同一个项目中调用云函数,你可以init firebase sdk并使用onCall方法。它会为你处理一切:

exports.newRequest = functions.https.onCall((data, context) => {
    console.log(`This is the received data: ${data}.`);
    return data;
})

像这样调用这个函数:

// Init the firebase SDK first    
const functions = firebase.functions();
const addMessage = functions.httpsCallable(`newRequest`);

Firebase文档:https://firebase.google.com/docs/functions/callable

如果你不能初始化SDK,以下是其他建议的精髓:

如果在默认位置使用firebase托管和主机,请选择“重写:https://firebase.google.com/docs/hosting/full-config#rewrites” 或者像krishnazden建议的那样使用CORS: https://stackoverflow.com/a/53845986/1293220

请参阅下面我如何设置我的快车与CORS。

“https://pericope。app'是我的Firebase项目的自定义域。

看起来所有其他答案都推荐起源:true或*。

我很犹豫是否允许所有的起源,因为它将允许任何人访问api。如果您正在创建一个公共服务,这是没问题的,但如果您正在使用您的数据做任何事情,这都是有风险的,因为它是一个特权环境。例如,这个管理SDK绕过您为Firestore或Storage设置的任何安全规则。

//Express
const express = require('express');
const app = express();

const cors = require('cors');
app.use(cors({
  origin: 'https://pericope.app'
}));

如果你在本地测试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!");
});

我是Firebase的初学者(30分钟前注册的)。我的问题是我调用了端点

https://xxxx-default-rtdb.firebaseio.com/myendpoint

而不是

https://xxxx-default-rtdb.firebaseio.com/myendpoint.json

如果您刚开始使用Firebase,请确保不要忘记.json扩展名。