And*_*kiy 98 javascript cors firebase google-cloud-functions
我目前正在学习如何为Firebase使用新的Cloud Functions,而我遇到的问题是我无法访问我通过AJAX请求编写的函数.我收到"No'Access-Control-Allow-Origin'"错误.这是我写的函数的一个例子:
exports.test = functions.https.onRequest((request, response) => {
response.status(500).send({test: 'Testing functions'});
})
Run Code Online (Sandbox Code Playgroud)
该函数位于以下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'});
})
})
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我很感激任何帮助.
更新:
道格史蒂文森的回答有所帮助.添加({产地:真})固定的问题,我也不得不改变response.status(500),以response.status(200)我在第一次完全错过.
Dou*_*son 118
Firebase团队提供了两个示例函数,用于演示CORS的使用:
第二个示例使用与您当前使用的不同的cors方式.
另外,请考虑像这样导入,如示例所示:
const cors = require('cors')({origin: true});
Run Code Online (Sandbox Code Playgroud)
dea*_*lls 40
您可以像这样设置云功能中的CORS response.set('Access-Control-Allow-Origin', '*');无需导入cors包
Yay*_*ano 25
对于试图在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
});
Run Code Online (Sandbox Code Playgroud)
小智 24
另外一条信息,只是为了一段时间之后用Google搜索这个:如果你正在使用firebase托管,你也可以设置重写,以便例如像(firebase_hosting_host)/ api/myfunction这样的网址重定向到( firebase_cloudfunctions_host)/ doStuff函数.这样,由于重定向是透明的并且是服务器端的,因此您不必处理cors.
您可以使用firebase.json中的重写部分进行设置:
"rewrites": [
{ "source": "/api/myFunction", "function": "doStuff" }
]
Run Code Online (Sandbox Code Playgroud)
Jaa*_*and 15
我对@Andreys回答他自己的问题有一点补充.
看起来您不必在cors(req, res, cb)函数中调用回调函数,因此您只需调用函数顶部的cors模块,而无需在回调中嵌入所有代码.如果你想在之后实施cors,这会快得多.
exports.exampleFunction = functions.https.onRequest((request, response) => {
cors(request, response, () => {});
return response.send("Hello from Firebase!");
});
Run Code Online (Sandbox Code Playgroud)
不要忘记在开幕式帖子中提到的init cors:
const cors = require('cors')({origin: true});
dim*_*mib 15
使用 Google Cloud Console 仪表板的简单解决方案:
“云函数”(“计算”部分)
选择您的云功能,例如“MyFunction”,右侧应出现一个侧面菜单,显示其访问控制设置
点击“添加成员”,输入“allUsers”并选择角色“Cloud Function Invoker”
保存 -> 现在,您应该在云函数列表中看到“允许未经身份验证”的备注
现在,每个人都可以通过互联网对 GCP 或 Firebase 项目进行正确的配置进行访问。(当心)
Mob*_*ent 14
Cloud Functions for Firebase v2cors现在允许您直接在 HTTP 选项中进行配置。它无需任何第三方软件包即可工作:
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
});
Run Code Online (Sandbox Code Playgroud)
谨防:
v2正在公开预览中。v1和函数。v2为了提高可读性,请分别更新您的导入以访问firebase-functions/v1或firebase-functions/v2。tbo*_*849 13
到目前为止,没有CORS解决方案对我有用。
不知道是否有人遇到过与我相同的问题,但是我以与发现的示例不同的5种方式设置了CORS,但似乎没有任何效果。我与Plunker一起建立了一个最小的示例,以查看它是否确实是一个错误,但是示例运行得很漂亮。我决定检查firebase功能日志(在firebase控制台中找到),看看是否可以告诉我任何事情。我在节点服务器的代码有一对夫妇的错误,不CORS相关的,当我调试释放了我CORS错误消息。我不知道为什么与CORS无关的代码错误会返回CORS错误响应,但它导致我在错误的兔子洞中呆了好几个小时...
tl; dr-检查Firebase功能日志是否没有CORS解决方案,并调试您遇到的任何错误
San*_*ndy 13
这可能会有所帮助。我使用 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);
Run Code Online (Sandbox Code Playgroud)
请确保您添加了重写部分
"rewrites": [
{
"source": "/api/v1/**",
"function": "functionName"
}
]
Run Code Online (Sandbox Code Playgroud)
Jer*_*yal 13
更新答案:使用cors支持 Typescript 的库:
安装 cors
npm i -S cors
npm i --save-dev @types/cors
Run Code Online (Sandbox Code Playgroud)
index.ts:
import * as cors from "cors";
const corsHandler = cors({ origin: true });
// allow cors in http function
export const myFunction = functions.https.onRequest((req, res) => {
corsHandler(req, res, async () => {
// your method body
});
});
Run Code Online (Sandbox Code Playgroud)
旧答案:(不再工作)
找到了一种无需导入任何“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();
});
Run Code Online (Sandbox Code Playgroud)
如果您不/不能使用 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));
}
Run Code Online (Sandbox Code Playgroud)
我刚刚发表了一篇文章:
https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html
通常,您应该使用Express CORS软件包,这需要一点点黑客来满足GCF/Firebase功能的要求.
希望有所帮助!
如果您没有捕获函数中的错误,则可能会发生 cors 错误。try catch我的建议是在你的 corsHandler 中实现
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
});
}
});
};
Run Code Online (Sandbox Code Playgroud)
用法:
exports.helloWorld = functions.https.onRequest((request, response) => {
corsHandler(request, response, () => {
functions.logger.info("Hello logs!");
response.send({
"data": "Hello from Firebase!"
});
});
});
Run Code Online (Sandbox Code Playgroud)
感谢 stackoverflow 用户:Hoang Trinh、Yayo Arellano和 Doug Stevenson
只有这种方式对我有用,因为我在我的请求中获得了授权:
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)
} )};
Run Code Online (Sandbox Code Playgroud)
如果有像我这样的人:如果你想从与云函数本身相同的项目中调用云函数,你可以初始化 firebase sdk 并使用 onCall 方法。它将为您处理一切:
exports.newRequest = functions.https.onCall((data, context) => {
console.log(`This is the received data: ${data}.`);
return data;
})
Run Code Online (Sandbox Code Playgroud)
像这样调用这个函数:
// Init the firebase SDK first
const functions = firebase.functions();
const addMessage = functions.httpsCallable(`newRequest`);
Run Code Online (Sandbox Code Playgroud)
Firebase 文档:https ://firebase.google.com/docs/functions/callable
如果您无法在此处初始化 SDK,则是其他建议的精髓:
| 归档时间: |
|
| 查看次数: |
64017 次 |
| 最近记录: |