我目前正在学习如何为Firebase使用新的云功能,而我遇到的问题是我无法访问我通过AJAX请求编写的功能。我得到了" No' 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的答案有所帮助。添加({origin:true})修复了问题,我还必须将response.status(500)
更改为response.status(200)
,我最初完全错过了。
答案 0 :(得分:90)
Firebase小组提供了两个sample functions来演示CORS的使用:
第二个示例使用与您当前使用的不同的cors方式。
另外,请考虑像这样导入,如示例所示:
import java.util.Arrays;
public class FindCommon {
/*
* @param a 3xN integer array, assume a is not null or empty
* @return the largest common number among a[0], a[1], a[2], null if no common number exists
*/
public static Integer getLargestCommonNumber(int[][] a) {
//Check if array is empty
if (a == null || a.length == 0){
return 0;
}
//Initialize
int [] Row1 = a[0];
int [] Row2 = a[1];
int [] Row3 = a[2];
Arrays.sort(a);
int i = 0, j = 0, k = 0;
// Iterate through three arrays while all arrays have elements
while (i < Row1.length && j < Row2.length && k < Row3.length)
{
if (Row1[i] > Row2[j] && Row2[j] > Row3[k]){
System.out.print(Row1[i]+" ");
int max = Row1[i];
}
else if (Row2[i] > Row1[j] && Row2[j] > Row3[k]){
System.out.print(Row2[i]+" ");
int max = Row2[i];
}
else if (Row3[i] > Row1[j] && Row3[j] > Row2[k]){
int max = Row3[i];
}
}
}
}
答案 1 :(得分:24)
您可以像这样response.set('Access-Control-Allow-Origin', '*');
在云功能中设置CORS,无需导入cors
程序包
答案 2 :(得分:21)
对于任何尝试在Typescript中执行此操作的人,代码如下:
LocalDate.of(2018, 1, 31).until(LocalDate.of(2018, 2, 28), ChronoUnit.MONTHS); // 0
LocalDate.of(2018, 1, 31).plusMonths(1); // but 2018-02-28
答案 3 :(得分:15)
我对@Andreys回答他自己的问题有一点补充。
您似乎无需在cors(req, res, cb)
函数中调用回调,因此您只需调用函数顶部的cors模块,而无需将所有代码嵌入回调函数中。如果你想在之后实施cors,这会快得多。
exports.exampleFunction = functions.https.onRequest((request, response) => {
cors(request, response, () => {});
return response.send("Hello from Firebase!");
});
不要忘记在开幕式中提到的初始角色:
const cors = require('cors')({origin: true});
答案 4 :(得分:14)
另外一条信息,仅仅是为了那些在一段时间后用Google搜索的信息: 如果您正在使用firebase托管,您还可以设置重写,以便例如像(firebase_hosting_host)/ api / myfunction这样的URL重定向到(firebase_cloudfunctions_host)/ doStuff函数。这样,由于重定向是透明的,服务器端,你不必处理cors。
您可以使用firebase.json中的重写部分进行设置:
"rewrites": [
{ "source": "/api/myFunction", "function": "doStuff" }
]
答案 5 :(得分:7)
找到了一种无需导入任何“ cors”库即可启用cors的方法。它也可以与Typescript
一起使用,并在chrome版本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();
});
答案 6 :(得分:6)
我刚刚发表了一篇文章:
https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html
通常,您应该使用Express CORS package,这需要一点点黑客来满足GCF / Firebase功能中的要求。
希望有所帮助!
答案 7 :(得分:6)
没有CORS解决方案对我有用……到目前为止!
不确定是否有人遇到过与我相同的问题,但是我以与发现的示例不同的5种方式设置了CORS,但似乎没有任何效果。我与Plunker一起建立了一个最小的示例,以查看它是否确实是一个错误,但是示例运行得很漂亮。我决定检查firebase功能日志(在firebase控制台中找到),看看是否可以告诉我任何事情。 我的节点服务器代码中有几个错误,与CORS不相关,是在调试时释放了我的CORS错误消息。我不知道为什么与CORS无关的代码错误会返回CORS错误响应,但是它导致我在错误的兔子洞中呆了好几个小时...
tl; dr-检查您的Firebase函数日志是否没有CORS解决方案,并调试您遇到的任何错误
答案 8 :(得分:2)
出于价值,我在将app
传递到onRequest
时遇到了同样的问题。我意识到问题是firebase函数的请求网址末尾有一个斜杠。 Express一直在寻找'/'
,但函数[project-id].cloudfunctions.net/[function-name]
的末尾没有斜杠。 CORS错误是假阴性。当我添加结尾斜杠时,我得到了期望的响应。
答案 9 :(得分:2)
只有当我在请求中获得授权时,这种方式才对我有用:
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)
} )};
答案 10 :(得分:2)
这可能会有所帮助。 我用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"
}
]
答案 11 :(得分:2)
将true
更改为"*"
对我来说是成功的秘诀,这就是它的样子:
const cors = require('cors')({ origin: "*" })
我尝试了这种方法,因为通常,这是设置此响应标头的方式:
'Access-Control-Allow-Origin', '*'
请注意,这将允许任何域调用您的端点,因此不安全。
此外,您可以阅读更多有关文档的信息: https://github.com/expressjs/cors
答案 12 :(得分:1)
经过如此多的搜索,我可以在同一个 firebase 文档中找到这个解决方案,只需在路径中实现 cors:
import * as express from "express";
import * as cors from "cors";
const api = express();
api.use(cors({ origin: true }));
api.get("/url", function);
链接 Firebase 文档:https://firebase.google.com/docs/functions/http-events
答案 13 :(得分:1)
如果您未在函数中发现错误,则可能会发生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
答案 14 :(得分:1)
使用Google Cloud Console仪表板的简单解决方案:
“云函数”(“计算”部分)
选择您的云功能,例如“ MyFunction”,应在右侧显示一个侧面菜单,向您显示其访问控制设置
单击“添加成员”,键入“ allUsers”,然后选择角色“ Cloud Function Invoker”
保存->现在,您应该在云功能列表中看到“允许未经身份验证”的注释
现在,通过正确配置GCP或Firebase项目,每个人都可以从Internet访问。 (请注意)
答案 15 :(得分:1)
我是 Firebase 的初学者(30 分钟前注册)。我的问题是我调用了我的端点
https://xxxx-default-rtdb.firebaseio.com/myendpoint
代替
https://xxxx-default-rtdb.firebaseio.com/myendpoint.json
如果您刚开始使用 Firebase,请确保不要忘记 .json
扩展。
答案 16 :(得分:1)
如果您要在本地测试Firebase应用,则需要将功能指向localhost
而不是云。默认情况下,当您在Web应用程序上使用功能时,firebase serve
或firebase emulators:start
会将功能指向服务器而不是localhost。
在firebase初始化脚本之后,在html头中添加以下脚本:
<script>
firebase.functions().useFunctionsEmulator('http://localhost:5001')
</script>
在将代码部署到服务器时,请确保删除此代码段。
答案 17 :(得分:0)
我已经尝试了很长时间了。
当我做出这个改变时,它终于奏效了。
app.get('/create-customer', (req, res) => {
return cors()(req, res, () => {
... your code ...
最大的不同在于我使用了 cors()(req, res...
而不是直接使用 cors(req, res...
它现在可以完美运行。
答案 18 :(得分:0)
如果您更喜欢制作单处理函数 (reference answer)
const applyMiddleware = handler => (req, res) => {
return cors(req, res, () => {
return handler(req, res)
})
}
exports.handler = functions.https.onRequest(applyMiddleware(handler))
答案 19 :(得分:0)
请参阅下文,了解我如何使用 CORS 设置 Express。
“https://pericope.app”是我的 Firebase 项目的自定义域。
看起来所有其他答案都推荐origin:true
或*
。
我对允许所有来源犹豫不决,因为它会允许其他任何人访问 api。如果您正在创建公共服务,那很好,但是如果您对数据做任何事情,那么它是有风险的,因为它是一个特权环境。例如,此管理 SDK 会绕过您为 Firestore 或 Storage 设置的任何安全规则。
//Express
const express = require('express');
const app = express();
const cors = require('cors');
app.use(cors({
origin: 'https://pericope.app'
}));
答案 20 :(得分:0)
我收到错误,因为我调用了一个在客户端不存在的函数。例如:
firebase.functions().httpsCallable('makeSureThisStringIsCorrect');
答案 21 :(得分:0)
在你的 https.onRequest 上使用 cors 和 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()}`);
});
});
来自Source
答案 22 :(得分:0)
增加我的经验。 我花了几个小时试图找出为什么发生CORS错误。
我已经重命名了我的云功能(这是我进行大升级后第一次尝试使用的功能)。
因此,当我的Firebase应用使用错误的名称调用云函数时,它应该抛出404错误,而不是CORS错误。
在我的Firebase应用程序中修复了云函数名称,从而解决了该问题。
我在这里填写了有关此问题的错误报告 https://firebase.google.com/support/troubleshooter/report/bugs
答案 23 :(得分:0)
如果其他解决方案均无效,则可以尝试在呼叫开始时添加以下地址以启用CORS-重定向:
带有JQuery AJAX请求的示例代码:
$.ajax({
url: 'https://cors-anywhere.herokuapp.com/https://fir-agilan.web.app/gmail?mail=asd@gmail.com,
type: 'GET'
});
答案 24 :(得分:0)
答案 25 :(得分:0)
如果您不使用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));
}
答案 26 :(得分:0)
如果外面有像我这样的人:如果要从与自己的云函数相同的项目中调用云函数,则可以初始化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,那么以下是其他建议的精髓:
答案 27 :(得分:0)
如果您不使用Express或只是想使用CORS。以下代码将帮助解决
const cors = require('cors')({ origin: true, });
exports.yourfunction = functions.https.onRequest((request, response) => {
return cors(request, response, () => {
// *Your code*
});
});