1

我使用 vuejs 构建了一个小型 Web 应用程序(www.suntax.de)并托管在 Google Firebase 上。我使用 Firebase 托管、数据库和函数。我使用函数在后端进行一些计算。

现在一切都在运行,但我在到达那里时遇到了一些麻烦,并且我想改进一些关于我的工作流程的事情。因此,我想向您解释我做了什么以及我现在在哪里挣扎。

首先,我设置了 vuejs applicationd 并将其部署到 firebase。我添加了我的自定义域,一切都很好。后来我实现了云功能,想从我的 vuejs 应用程序中进行调用。之后firebase deploy,我可以在浏览器中调用这个函数,它工作正常: https://us-central1-suntax-6d0ea.cloudfunctions.net/calcEEGcompensation?year=2013&month=1&size=10

现在我想,我只是从我的 vuejs 应用程序中调用函数的 URL。但后来我收到以下错误消息: [Error] Origin * is not allowed by Access-Control-Allow-Origin.

然后我读到我必须在以下rewrite内容中添加一个部分firebase.json

现在我的 firebase.json 看起来像这样:

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    // Add the following rewrites section *within* "hosting"
   "rewrites": [ {
      "source": "/calcEEGcompensation", "function": "calcEEGcompensation"
    } ]
  }
}

现在我可以使用以下 URL 调用我的 firebase 函数: https://www.suntax.de/calcEEGcompensation?year=2013&month=1&size=10

在我的 vuejs 应用程序中集成上述 URL 后,应用程序在部署到 firebase 服务器后运行良好。

由于我想不断改进应用程序,我想在部署之前在本地测试所有内容。

我知道我可以通过以下方式在本地运行 firebase 托管和功能: firebase serve --only functions,hosting

但是,现在我的应用程序对我的函数进行了硬编码调用https://www.suntax.de/calcEEGcompensation?year=2013&month=1&size=10,这再次导致错误[Error] Origin * is not allowed by Access-Control-Allow-Origin.

但也将 URL 更改为本地函数 http://localhost:5001/suntax-6d0ea/us-central1/calcEEGcompensation?year=2013&month=1&size=10 会导致错误消息 [Error] Origin * is not allowed by Access-Control-Allow-Origin.

一些进一步的阅读使我找到了解决方案cors。所以我将我的功能更改为:

const functions = require('firebase-functions');
const cors = require('cors')({origin: true});

exports.calcEEGcompensation = functions.https.onRequest((req, res) => {
    cors(req, res, () => {
        const yearOfCommissioning = req.query.year;
        const monthOfCommissioning = req.query.month;
        const pvsystemsize = req.query.size;

        ...

        res.send("hello");
    });
});

这有帮助,现在一切正常: - 部署的应用程序仍然运行良好。- 我可以在调用本地函数和部署函数的同时在本地运行应用程序。我只需要更改函数的 URL。

但现在这是我的问题:我能以更好的方式解决这个问题吗?如果我在本地测试 vuejs 应用程序和函数,我必须在部署之前更改函数 URL。然后我必须在本地测试时将其改回。如果没有cors.

我理想的解决方案是有一个设置,可以在本地进行全面测试,并且可以在firebase deploy不更改 URL 的情况下轻松部署。这可能吗?

谢谢和最好的问候,克里斯托夫

4

2 回答 2

2

我找到了非常简单的解决方案,并且完全符合我的要求。我不知道为什么我以前没有弄清楚。这是我所做的:

我只是从我的 firebase 托管中调用相对 URL:

calcEEGcompensation?year=2013&month=1&size=10

如果重写设置正确,一切正常firebase.json

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    // Add the following rewrites section *within* "hosting"
   "rewrites": [ {
      "source": "/calcEEGcompensation", "function": "calcEEGcompensation"
    } ]
  }
}

设置完这样的所有内容后,我可以执行firebase serve --only functions,hosting并且可以在本地测试所有内容。执行后firebase deploy,一切都在服务器上顺利运行。

我不需要cors

感谢@wonsuc 的回答。

于 2018-03-17T20:04:48.463 回答
1

更新(对于 Firebase 托管):
目前没有解决方法可以使用 Firebase 托管 SDK 解决。
但是还有另一种方法可以实现这一目标。

在您的托管源中尝试以下代码。

if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') {
    console.log('It's a local server!');
}

在我看来,这些是目前检查开发环境的最佳方式。
因此,您应该location.hostname在 Firebase 托管和server.address()Cloud Functions 中使用。

并使用常量变量定义您的 Functions 端点。

const DEBUG = location.hostname === 'localhost' || location.hostname === '127.0.0.1';
const FUNCTIONS_ENDPOINT_DEV = 'http://localhost:5001/';
const FUNCTIONS_ENDPOINT_PRD = 'https://us-central1-something.cloudfunctions.net/';
const FUNCTIONS_URL_CALC = 'calcEEGcompensation?year=2013&month=1&size=10';

var endpoint;
if (DEBUG) {
    endpoint = FUNCTIONS_ENDPOINT_DEV + FUNCTIONS_URL_CALC;
} else {
    endpoint = FUNCTIONS_ENDPOINT_PRD + FUNCTIONS_URL_CALC;
}

原始答案(对于 Firebase 的云功能):
您是否尝试过 node.js 网络模块的server.address()功能?
此方法将告诉您您的函数代码是在运行localhost还是实际部署的服务器上运行。

例如,您可以像这样使用。

const server = app.listen(function() {
    let host = server.address().address;
    let port = server.address().port;

    if (!host || host === '::') {
        host = 'localhost:';
    }

    console.log('Server is running on %s%s', host, port);
});
于 2018-03-04T22:44:19.460 回答