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


当前回答

在https上使用cors。onRequest与Typescript像这样:

import * as cors from 'cors';
const corsHandler = cors({origin: true});

export const pingFunctionWithCorsAllowed = functions.https.onRequest((request, response) => {
  corsHandler(request, response, () => {
    response.send(`Ping from Firebase (with CORS handling)! ${new Date().toISOString()}`);
  });
});

从源

其他回答

我得到了错误,因为我调用了一个在客户端不存在的函数。例如:

firebase.functions().httpsCallable('makeSureThisStringIsCorrect');

如果有像我这样的人:如果你想在同一个项目中调用云函数,你可以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

我已经试了很长时间了。

当我做出这个改变时,它终于起作用了。

app.get('/create-customer', (req, res) => {
  return cors()(req, res, () => {
    ... your code ...

最大的区别是我使用了cors()(req, res…而不是直接cors(req, res…

它现在工作得很完美。

我刚刚发表了一篇关于这方面的文章:

https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html

通常,您应该使用Express CORS包,它需要一些hack才能满足GCF/Firebase Functions中的要求。

希望有帮助!

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