【问题标题】:Firebase Cloud Function does not execute when called from web client served by Netlify从 Netlify 提供的 Web 客户端调用时,Firebase Cloud Function 不执行
【发布时间】:2021-12-12 04:51:19
【问题描述】:

我一直在尝试调用 Firebase Cloud Function,但没有成功。

成功部署的函数是:

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 Cloud 控制台测试/运行该功能时,两个日志都会显示。

在 Web 客户端中,我收到错误消息:

从源“https://my-client-url”访问“https://us-central1-my-project.cloudfunctions.net/create-auth-aoken?ot-auth-code=xyz”获取' 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

所以我按照文档的建议解决了 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 问题,但它不起作用。

我应该如何准确地配置它以使其工作?

【问题讨论】:

  • 你可以尝试做return cors(request, response, () => {...}(即添加return)吗?
  • 感谢@RenaudTarnec,虽然我刚刚测试过,但没有任何改变

标签: node.js firebase google-cloud-functions


【解决方案1】:

我无法解决 CORS 问题,但我确实设法通过使用 functions.https.onCall 而不是 functions.https.onRequest 最终使云功能正常工作。我找到了这个答案https://stackoverflow.com/a/51477892/11584105 并关注了这些官方文档:https://firebase.google.com/docs/functions/callable#web-version-9

【讨论】:

    【解决方案2】:

    这当然是可能的;我将此解决方案用于我自己滚动的 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 请求并以“是的,你可以”响应 - 其他请求(例如 GET/POST)它只是传递给给定函数。它可用于包装您的端点并正确响应来自浏览器的 CORS 调用。

    所以实际的终点是这样表示的:

    exports.myFunction = MakeCORSRequest(async (req, response) => {
       //Do your stuff here
    })
    

    【讨论】:

    • 感谢@Elemental,我使用了您的确切代码,但是当我从 Netlify 上提供的 React 应用程序调用该函数时,我仍然收到 CORS 错误。
    • 我上面的代码只允许 GET 和 POST 如果你使用其他位,你需要修改它
    • 从哪里调用函数并不重要——你确定你理解我的第二段代码吗(即你需要使用 MakeCORSRequest 而不是使用 function.https.onRequest端点函数)
    【解决方案3】:

    这可以通过多种方式解决,一种是将您的请求发送到代理服务器。您的请求将如下所示:

    https://cors-anywhere.herokuapp.com/https://joke-api-strict-cors.appspot.com/jokes/random
    

    这是一个简单的解决方案,适用于开发环境,因为它是在浏览器到服务器的通信上实现的。缺点是您的请求可能需要一段时间才能收到响应,因为高延迟使其看起来很慢,并且可能不适合生产环境。

    另一种选择是尝试将 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: * 标头应用于来自服务器的每个请求。 同源策略不会介入阻止请求,即使域不同。

    您可以查看有关如何修复 CORS 错误的完整文档:

    【讨论】:

    • 谢谢@Robert G!我将研究这些解决方案。但是您是说,我想要做的事情对于像我这样的直接客户端到云功能解决方案根本不可能?
    • 在 Firebase Function 中启用 CORS 的方法有很多。我的答案中的示例代码只是将 CORS 与 Express 结合使用。
    猜你喜欢
    • 1970-01-01
    • 2020-08-03
    • 2020-01-05
    • 2021-05-02
    • 2019-10-09
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 2019-10-19
    相关资源
    最近更新 更多