从 Netlify 服务的 Web 客户端调用时,Firebase Cloud Function 不执行
Firebase Cloud Function does not execute when called from web client served by Netlify
我一直在尝试调用 Firebase 云函数,但没有成功。
部署成功的函数为:
functions.logger.info("Hello logs!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); // this logs
exports.createAuthToken = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", { structuredData: true }); // this doesn't log
response.send("Hello from Firebase!");
});
代码的第一行显示在日志中,但从外部 Web 客户端调用时第三行没有。当我从 Google 云控制台测试 /运行 函数时,两个日志都会显示。
在 Web 客户端中,我收到错误消息:
Access to fetch at 'https://us-central1-my-project.cloudfunctions.net/create-auth-aoken?ot-auth-code=xyz' from origin 'https://my-client-url' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
所以我按照文档中的建议解决了 cors 问题:
const cors = require('cors')({
origin: true,
});
functions.logger.info("Hello logs!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); // this logs
exports.createAuthToken = functions.https.onRequest((request, response) => {
cors(request, response, () => {
functions.logger.info("Hello logs >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>!", { structuredData: true }); // this still doesn't
response.send("Hello from Firebase!");
});
});
我这样调用函数:
https://us-central1-my-project.cloudfunctions.net/create-auth-token?ot-auth-code=${code}&id-token=${token}
我已经尝试用我能找到的所有方法解决 cors 问题,但它不起作用。
我应该如何正确配置它才能使其正常工作?
这可以通过多种方式解决,一种是将您的请求发送到代理服务器。您的请求将如下所示:
https://cors-anywhere.herokuapp.com/https://joke-api-strict-cors.appspot.com/jokes/random
这是一个简单的解决方案,适用于开发环境,因为它是在 browser-to-server 通信上实现的。缺点是您的请求可能需要一段时间才能收到响应,因为高延迟使其看起来很慢,并且可能不适合生产环境。
另一种选择是尝试将 CORS 与 Express 结合使用。检查下面的 Node.js
代码:
const express = require('express');
const request = require('request');
const app = express();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
app.get('/jokes/random', (req, res) => {
request(
{ url: 'https://joke-api-strict-cors.appspot.com/jokes/random' },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).json({ type: 'error', message: err.message });
}
res.json(JSON.parse(body));
}
)
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));
这个将作为中间件将 Access-Control-Allow-Origin: *
header 应用于来自服务器的每个请求。 Same-origin 策略 即使域不同也不会介入阻止请求。
您可以查看有关如何修复 CORS 错误的完整文档:
当然可以;我将此解决方案用于 firebase,我自己滚动以简单地响应 CORS 请求:
function MakeCORSRequest(func) {
return functions.https.onRequest((req, res) => {
res.set('Access-Control-Allow-Origin', '*');
if (req.method === 'OPTIONS') {
// Send response to OPTIONS requests
res.set('Access-Control-Allow-Methods', 'GET, POST');
res.set('Access-Control-Allow-Headers', 'Content-Type');
res.set('Access-Control-Max-Age', '3600');
res.status(204).send('');
} else {
return func(req, res);
}
});
}
它所做的只是拦截 CORS OPTIONS 请求并用 'Yes you can' 响应 - 其他请求(例如 GET/POST)它只是传递给给定的函数。它可用于包装您的端点并正确响应来自浏览器的 CORS 调用。
所以实际的终点是这样表示的:
exports.myFunction = MakeCORSRequest(async (req, response) => {
//Do your stuff here
})
我无法解决 CORS 问题,但我确实设法通过使用 functions.https.onCall
而不是 functions.https.onRequest
使云功能最终起作用。我找到了这个答案 and followed these official docs: https://firebase.google.com/docs/functions/callable#web-version-9
我一直在尝试调用 Firebase 云函数,但没有成功。
部署成功的函数为:
functions.logger.info("Hello logs!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); // this logs
exports.createAuthToken = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", { structuredData: true }); // this doesn't log
response.send("Hello from Firebase!");
});
代码的第一行显示在日志中,但从外部 Web 客户端调用时第三行没有。当我从 Google 云控制台测试 /运行 函数时,两个日志都会显示。
在 Web 客户端中,我收到错误消息:
Access to fetch at 'https://us-central1-my-project.cloudfunctions.net/create-auth-aoken?ot-auth-code=xyz' from origin 'https://my-client-url' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
所以我按照文档中的建议解决了 cors 问题:
const cors = require('cors')({
origin: true,
});
functions.logger.info("Hello logs!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); // this logs
exports.createAuthToken = functions.https.onRequest((request, response) => {
cors(request, response, () => {
functions.logger.info("Hello logs >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>!", { structuredData: true }); // this still doesn't
response.send("Hello from Firebase!");
});
});
我这样调用函数:
https://us-central1-my-project.cloudfunctions.net/create-auth-token?ot-auth-code=${code}&id-token=${token}
我已经尝试用我能找到的所有方法解决 cors 问题,但它不起作用。
我应该如何正确配置它才能使其正常工作?
这可以通过多种方式解决,一种是将您的请求发送到代理服务器。您的请求将如下所示:
https://cors-anywhere.herokuapp.com/https://joke-api-strict-cors.appspot.com/jokes/random
这是一个简单的解决方案,适用于开发环境,因为它是在 browser-to-server 通信上实现的。缺点是您的请求可能需要一段时间才能收到响应,因为高延迟使其看起来很慢,并且可能不适合生产环境。
另一种选择是尝试将 CORS 与 Express 结合使用。检查下面的 Node.js
代码:
const express = require('express');
const request = require('request');
const app = express();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
app.get('/jokes/random', (req, res) => {
request(
{ url: 'https://joke-api-strict-cors.appspot.com/jokes/random' },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).json({ type: 'error', message: err.message });
}
res.json(JSON.parse(body));
}
)
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));
这个将作为中间件将 Access-Control-Allow-Origin: *
header 应用于来自服务器的每个请求。 Same-origin 策略 即使域不同也不会介入阻止请求。
您可以查看有关如何修复 CORS 错误的完整文档:
当然可以;我将此解决方案用于 firebase,我自己滚动以简单地响应 CORS 请求:
function MakeCORSRequest(func) {
return functions.https.onRequest((req, res) => {
res.set('Access-Control-Allow-Origin', '*');
if (req.method === 'OPTIONS') {
// Send response to OPTIONS requests
res.set('Access-Control-Allow-Methods', 'GET, POST');
res.set('Access-Control-Allow-Headers', 'Content-Type');
res.set('Access-Control-Max-Age', '3600');
res.status(204).send('');
} else {
return func(req, res);
}
});
}
它所做的只是拦截 CORS OPTIONS 请求并用 'Yes you can' 响应 - 其他请求(例如 GET/POST)它只是传递给给定的函数。它可用于包装您的端点并正确响应来自浏览器的 CORS 调用。
所以实际的终点是这样表示的:
exports.myFunction = MakeCORSRequest(async (req, response) => {
//Do your stuff here
})
我无法解决 CORS 问题,但我确实设法通过使用 functions.https.onCall
而不是 functions.https.onRequest
使云功能最终起作用。我找到了这个答案