在Firebase的云功能中启用CORS

2020/11/13 23:23 · javascript ·  · 0评论

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

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

该函数位于以下网址中: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'});
   })
})

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

更新:

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

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

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

考虑像这样导入,如示例所示:

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

函数的一般形式如下所示:

exports.fn = functions.https.onRequest((req, res) => {
    cors(req, res, () => {
        // your function body here - use the provided req and res from cors
    })
});

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

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

无需导入cors

对于任何尝试在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
});

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

您可以在firebase.json中通过重写部分进行设置:

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

除了@Andreys回答他自己的问题外,我还有一点补充。

似乎您不必在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解决方案对我有用。

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

tl; dr-检查您的Firebase功能日志是否没有CORS解决方案,并调试您拥有的任何错误

这可能会有所帮助。我用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);

请确保您添加了重写部分

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

我刚刚发表了一点关于:

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

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

希望有帮助!

找到了一种无需导入任何“ cors”库即可启用cors的方法。它还可以与Typescriptchrome版本81.0一起使用并进行测试。

exports.createOrder = functions.https.onRequest((req, res) => {
// browsers like chrome need these headers to be present in response if the api is called from other than its base domain
  res.set("Access-Control-Allow-Origin", "*"); // you can also whitelist a specific domain like "http://127.0.0.1:4000"
  res.set("Access-Control-Allow-Headers", "Content-Type");

  // your code starts here

  //send response
  res.status(200).send();
});

只有这种方式对我有效,因为我已获得请求的授权:

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)
} )};

如果外面有像我这样的人:如果要从与自己的云函数相同的项目中调用云函数,则可以初始化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,则这里是其他建议的本质:

如果您不/不能使用cors插件,则setCorsHeaders()在处理程序函数中首先调用该函数也将起作用。

回复时,也使用responseSuccess / Error函数。

const ALLOWED_ORIGINS = ["http://localhost:9090", "https://sub.example.com", "https://example.com"]


// Set CORS headers for preflight requests
function setCorsHeaders (req, res) {
  var originUrl = "http://localhost:9090"


  if(ALLOWED_ORIGINS.includes(req.headers.origin)){
    originUrl = req.headers.origin
  }

  res.set('Access-Control-Allow-Origin', originUrl);
  res.set('Access-Control-Allow-Credentials', 'true');

  if (req.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    res.set('Access-Control-Allow-Methods', 'GET,POST','PUT','DELETE');
    res.set('Access-Control-Allow-Headers', 'Bearer, Content-Type');
    res.set('Access-Control-Max-Age', '3600');
    res.status(204).send('');
  }
}

function respondError (message, error, code, res) {
  var response = {
    message: message,
    error: error
  }
  res.status(code).end(JSON.stringify(response));
}


function respondSuccess (result, res) {
  var response = {
    message: "OK",
    result: result
  }
  res.status(200).end(JSON.stringify(response));
}

值得的是,app进入时我遇到了同样的问题onRequest我意识到问题是firebase函数的请求URL末尾有一个斜杠。Express在寻找,'/'但是我没有在函数上加上斜线[project-id].cloudfunctions.net/[function-name]CORS错误是假阴性。当我添加结尾斜杠时,我得到了期望的响应。

如果您要在本地测试Firebase应用,则需要将功能指向localhost而不是云。默认情况下,firebase servefirebase emulators:start在Web应用程序上将功能指向服务器而不是localhost时使用。

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

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

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

改变对我来说true"*"成功的窍门,所以它看起来像这样:

const cors = require('cors')({ origin: "*" })

我尝试了这种方法,因为通常,这是设置此响应标头的方式:

'Access-Control-Allow-Origin', '*'

请注意,这将允许任何域调用您的端点,因此并不安全。

此外,您可以在文档上阅读更多信息:https :
//github.com/expressjs/cors

如果您不使用Express或只是想使用CORS。以下代码将有助于解决

const cors = require('cors')({ origin: true, });   
exports.yourfunction = functions.https.onRequest((request, response) => {  
   return cors(request, response, () => {  
        // *Your code*
    });
});

使用Google Cloud Console仪表板的简单解决方案:

  1. 转到您的GCP控制台信息中心:

https://console.cloud.google.com/home/dashboard

  1. 进入菜单

“云函数”(“计算”部分)

  1. 选择您的云功能,例如“ MyFunction”,右侧菜单将出现,向您显示其访问控制设置

  2. 单击“添加成员”,键入“ allUsers”,然后选择角色“ Cloud Function Invoker”

  3. 保存->现在,您应该在云功能列表中看到“允许未经身份验证”的注释

现在,通过正确配置GCP或Firebase项目,每个人都可以从Internet访问。注意

在我的情况下,该错误是由云函数调用程序限制访问引起的。请将allUsers添加到云函数调用程序。点击链接请参阅文章以获取更多信息

如果其他解决方案均无效,则可以尝试在呼叫开始时添加以下地址以启用CORS-重定向:

https://cors-anywhere.herokuapp.com/

带有JQuery AJAX请求的示例代码:

$.ajax({
   url: 'https://cors-anywhere.herokuapp.com/https://fir-agilan.web.app/gmail?mail=asd@gmail.com,
   type: 'GET'
});

增加我的经验。我花了几个小时试图找出为什么我有CORS错误。

碰巧,我已经重命名了我的云功能(在进行大升级之后,我第一次尝试使用该功能)。

因此,当我的Firebase应用使用错误的名称调用云函数时,它应该抛出404错误,而不是CORS错误。

在我的Firebase应用程序中修复了云函数名称,从而解决了该问题。

我已经在这里https://firebase.google.com/support/troubleshooter/report/bugs填写了有关此问题的错误报告

本文地址:http://javascript.askforanswer.com/zaifirebasedeyungongnengzhongqiyongcors.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!