Javascript 在 Cloud Functions 中为 Firebase 启用 CORS

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42755131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:24:52  来源:igfitidea点击:

Enabling CORS in Cloud Functions for Firebase

javascriptfirebasecorsgoogle-cloud-functions

提问by Andrey Pokrovskiy

I'm currently learning how to use new Cloud Functions for Firebase and the problem I'm having is that I can't access the function I wrote through an AJAX request. I get the "No 'Access-Control-Allow-Origin'" error. Here's an example of the function I wrote:

我目前正在学习如何为 Firebase 使用新的 Cloud Functions,我遇到的问题是我无法访问我通过 AJAX 请求编写的函数。我收到“没有'访问控制-允许-来源'”错误。这是我编写的函数的示例:

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

The function sits in this url: https://us-central1-fba-shipper-140ae.cloudfunctions.net/test

该函数位于此 url:https: //us-central1-fba-shipper-140ae.cloudfunctions.net/test

Firebase docs suggests to add CORS middleware inside the function, I've tried it but it's not working for me: https://firebase.google.com/docs/functions/http-events

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

This is how I did it:

我是这样做的:

var cors = require('cors');    

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

What am I doing wrong? I would appreciate any help with this.

我究竟做错了什么?我将不胜感激。

UPDATE:

更新:

Doug Stevenson's answer helped. Adding ({origin: true}) fixed the issue, I also had to change response.status(500)to response.status(200)which I completely missed at first.

道格史蒂文森的回答有所帮助。添加({产地:真})固定的问题,我也不得不改变response.status(500)response.status(200)我完全错过了在第一。

回答by Doug Stevenson

There are two sample functionsprovided by the Firebase team that demonstrate the use of CORS:

Firebase 团队提供了两个示例函数来演示 CORS 的使用:

The second sample uses a different way of working with cors than you're currently using.

第二个示例使用与您当前使用的 cors 不同的方式。

Also, consider importing like this, as shown in the samples:

另外,请考虑像这样导入,如示例中所示:

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

回答by deanwilliammills

You can set the CORS in the cloud function like this

您可以像这样在云功能中设置 CORS

response.set('Access-Control-Allow-Origin', '*');

response.set('Access-Control-Allow-Origin', '*');

No need to import the corspackage

无需导入cors

回答by Yayo Arellano

For anyone trying to do this in Typescript this is the code:

对于任何试图在 Typescript 中执行此操作的人,代码如下:

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

export const exampleFunction= functions.https.onRequest(async (request, response) => {
       corsHandler(request, response, () => {});
       //Your code here
});

回答by Pablo Urquiza

One additional piece of info, just for the sake of those googling this after some time: If you are using firebase hosting, you can also set up rewrites, so that for example a url like (firebase_hosting_host)/api/myfunction redirects to the (firebase_cloudfunctions_host)/doStuff function. That way, since the redirection is transparent and server-side, you don't have to deal with cors.

一条额外的信息,只是为了那些在一段时间后使用谷歌搜索的人:如果您使用的是 firebase 托管,您还可以设置重写,以便例如像 (firebase_hosting_host)/api/myfunction 这样的 url 重定向到 ( firebase_cloudfunctions_host)/doStuff 函数。这样,由于重定向是透明的和服务器端的,您不必处理 cors。

You can set that up with a rewrites section in firebase.json:

您可以使用 firebase.json 中的重写部分进行设置:

"rewrites": [
        { "source": "/api/myFunction", "function": "doStuff" }
]

回答by tbone849

No CORS solutions worked for me... till now!

没有 CORS 解决方案对我有用......直到现在!

Not sure if anyone else ran into the same issue I did, but I set up CORS like 5 different ways from examples I found and nothing seemed to work. I set up a minimal example with Plunker to see if it was really a bug, but the example ran beautifully. I decided to check the firebase functions logs (found in the firebase console) to see if that could tell me anything. I had a couple errors in my node server code, not CORS related, that when I debugged released me of my CORS error message. I don't know why code errors unrelated to CORS returns a CORS error response, but it led me down the wrong rabbit hole for a good number of hours...

不确定其他人是否遇到了与我相同的问题,但我从我发现的示例中以 5 种不同的方式设置了 CORS,但似乎没有任何效果。我用 Plunker 设置了一个最小的例子来看看它是否真的是一个错误,但这个例子运行得很好。我决定检查 firebase 函数日志(在 firebase 控制台中找到),看看是否可以告诉我任何信息。我在节点服务器的代码有一对夫妇的错误不CORS相关的,当我调试释放了我CORS错误消息。我不知道为什么与 CORS 无关的代码错误会返回 CORS 错误响应,但它使我陷入了错误的兔子洞好几个小时......

tl;dr - check your firebase function logs if no CORS solutions work and debug any errros you have

tl; dr - 如果没有 CORS 解决方案工作,请检查您的 firebase 功能日志并调试您拥有的任何错误

回答by Jaap Weijland

I have a little addition to @Andreys answer to his own question.

我对@Andreys 对他自己的问题的回答有一点补充。

It seems that you do not have to call the callback in the cors(req, res, cb)function, so you can just call the cors module at the top of your function, without embedding all your code in the callback. This is much quicker if you want to implement cors afterwards.

似乎您不必在cors(req, res, cb)函数中调用回调,因此您只需调用函数顶部的 cors 模块即可,而无需将所有代码嵌入到回调中。如果您想在之后实施 cors,这会快得多。

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

Do not forget to init cors as mentioned in the opening post:

不要忘记在开篇文章中提到初始化 cors:

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

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

回答by Sandy

This might be helpful. I created firebase HTTP cloud function with express(custom URL)

这可能会有所帮助。我使用 express(自定义 URL)创建了 Firebase HTTP 云功能

const express = require('express');
const bodyParser = require('body-parser');
const cors = require("cors");
const app = express();
const main = express();

app.post('/endpoint', (req, res) => {
    // code here
})

app.use(cors({ origin: true }));
main.use(cors({ origin: true }));
main.use('/api/v1', app);
main.use(bodyParser.json());
main.use(bodyParser.urlencoded({ extended: false }));

module.exports.functionName = functions.https.onRequest(main);

Please make sure you added rewrite sections

请确保您添加了重写部分

"rewrites": [
      {
        "source": "/api/v1/**",
        "function": "functionName"
      }
]

回答by mhaligowski

I have just published a little piece on that:

我刚刚发表了一篇关于这个的小文章:

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

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

Generally, you should use Express CORS package, which requires a little hacking around to meet the requirements in GCF/Firebase Functions.

通常,您应该使用 Express CORS 包,这需要稍微修改一下才能满足 GCF/Firebase 函数中的要求。

Hope that helps!

希望有帮助!

回答by Chronnie

If there are people like me out there: If you want to call the cloud function from the same project as the cloud function it self, you can init the firebase sdk and use onCall method. It will handle everything for you:

如果有像我这样的人:如果你想从与云函数本身相同的项目中调用云函数,你可以初始化 firebase sdk 并使用 onCall 方法。它将为您处理一切:

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

Call this function like this:

像这样调用这个函数:

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

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

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

If you can't init the SDK here is the essence from the other suggestions:

如果您无法在此处初始化 SDK,则是其他建议的精髓:

回答by Gleb Dolzikov

Only this way works for me as i have authorization in my request:

只有这种方式对我有用,因为我在我的请求中获得了授权:

exports.hello = functions.https.onRequest((request, response) => {
response.set('Access-Control-Allow-Origin', '*');
response.set('Access-Control-Allow-Credentials', 'true'); // vital
if (request.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    response.set('Access-Control-Allow-Methods', 'GET');
    response.set('Access-Control-Allow-Headers', 'Content-Type');
    response.set('Access-Control-Max-Age', '3600');
    response.status(204).send('');
} else {
    const params = request.body;
    const html = 'some html';
    response.send(html)
} )};