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


当前回答

Firebase v2的云功能

Firebase v2的云函数现在允许您直接在HTTP选项中配置cors。它的工作不需要任何第三方软件包:


import { https } from 'firebase-functions/v2';

export myfunction = https.onRequest({ cors: true }, async (req, res) => {
  // this will be invoked for any request, regardless of its origin
});

请注意:

在撰写本文时,v2正在公开预览中。 目前v2中只支持区域的一个子集。 函数名被限制为小写字母、数字和破折号。 你可以在一个代码库中同时使用v1和v2函数。为了提高可读性,请更新导入以分别访问firebase-functions/v1或firebase-functions/v2。

其他回答

云功能日志有助于检查您是否卡住了。

我的问题原来是我的云函数上的一个类型错误,我有一个数字,其中一个字符串是预期的:

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received type number (1)

出于某种原因,这给了我cors错误的前端,它成为了几个小时的浪费。

在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()}`);
  });
});

从源

如果你不/不能使用cors插件,在处理函数中首先调用setCorsHeaders()函数也可以工作。

在回复时也使用respondSuccess/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));
}

一个额外的信息,只是为了那些在一段时间后谷歌这个:

如果你正在使用firebase托管,你也可以设置重写,例如一个url (firebase_hosting_host)/api/myfunction重定向到(firebase_cloudfunctions_host)/doStuff函数。这样,由于重定向是透明的并且是服务器端的,所以您不必处理cors。

你可以在firebase.json中设置一个重写部分:

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

补充我的经验。 我花了几个小时试图找到为什么我有CORS错误。

碰巧我重命名了我的云功能(这是我在一次大升级后尝试的第一次)。

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

修复我的firebase应用程序中的云函数名称修复了这个问题。

我在这里填了一份关于这个的错误报告 https://firebase.google.com/support/troubleshooter/report/bugs