使用 Cloud Functions 提供动态内容

使用 Firebase 托管时,您可以使用 Cloud Functions 来处理服务器端事务。这意味着您可以为 Firebase 托管站点动态生成内容。可以执行的操作如下所示:

  • 提供动态内容。您可以通过函数执行服务器端逻辑以返回动态生成的响应,而不是仅提供静态内容。例如,您可以使用类似 /blog/<id-for-blog-post> 这样的网址。此网址模式可以指向一个函数,该函数以动态方式使用网址中的博文 ID 参数从您的 Firebase 实时数据库动态检索内容。
  • 预渲染单页应用以改进 SEO。这样您就可以创建动态 meta 标记,以便在不同社交网络上共享。
  • 使网页应用保持轻量级。您可以通过 Cloud Functions 为 Firebase 托管站点创建 API,以异步检索内容。这样您可以通过使客户端代码保持轻量级,并通过函数异步加载内容,来减少网页应用的初始加载时间。

将 Cloud Functions 连接到 Firebase 托管

要将函数连接到 Firebase 托管,您需要设置 Cloud Functions、编写函数、创建重写规则并部署更改。为了改进动态内容的性能,您可以选择调整缓存设置。以下示例演示了如何实现此目的。

为 Firebase 托管设置 Cloud Functions

如果您已经为 Firebase 设置了 Cloud Functions,可以跳过此步骤并继续执行“创建 HTTPS 函数”。这将为您的 Firebase 项目设置 Cloud Functions。

首先确保您已安装最新版本的 Firebase CLI,它需要 Node.js 6.3.1 或更高版本。您可以按照 https://nodejs.org/ 上的说明安装 Node。安装 Node.js 将同时安装 npm

要检查您正在运行的 Node.js 的版本,请在终端运行以下命令:

node --version

您可以通过在终端运行以下命令来安装最新版本的 Firebase CLI:

npm install -g firebase-tools

更新 Firebase CLI 后,您必须初始化函数。如果您尚未初始化托管项目,请运行以下命令,并在出现提示时选择在项目目录中初始化托管和 Cloud Functions。

firebase init

如果您有一个现有的托管项目,请在您的项目目录中运行以下命令,以仅初始化 Cloud Functions。

firebase init functions

为您的托管网站创建 HTTP 函数

在您喜欢的编辑器中打开 /functions/index.js,并将其内容替换为以下代码。这将创建一个名为 bigben 的简单 HTTPS 函数。

const functions = require('firebase-functions');

exports.bigben = functions.https.onRequest((req, res) => {
  const hours = (new Date().getHours() % 12) + 1 // london is UTC + 1hr;
  res.status(200).send(`<!doctype html>
    <head>
      <title>Time</title>
    </head>
    <body>
      ${'BONG '.repeat(hours)}
    </body>
  </html>`);
});

将托管请求定向到您的函数

通过重写规则,您可以将匹配特定模式的请求定向到单个目标。例如,为了将您的托管网站上页面 /bigben 收到的所有请求定向到 bigben 函数,您将打开 firebase.json 并在 hosting 部分下添加以下 rewrite 配置。

{
  "hosting": {
    "public": "public",

    // Add the following rewrites section *within* "hosting"
   "rewrites": [ {
      "source": "/bigben", "function": "bigben"
    } ]

  }
}

如需要,您可以详细了解重写规则

在本地运行动态内容

您可以使用 Firebase CLI 在本地部署和运行动态内容,这样就能在部署正式版网站之前对其进行测试。

要使用此功能,firebase-tools 必须为 3.8.0 版或更高版本,firebase-functions SDK 必须为 0.5.7 版或更高版本。要更新二者,请在项目的 functions/ 目录中运行以下命令:

npm install --save firebase-functions@latest
npm install -g firebase-tools

要在本地运行动态内容,请使用 firebase serve

firebase serve --only hosting,functions # emulates local hosting code and local functions code
firebase serve --only hosting # emulates local hosting code, but uses production functions as proxies.

此命令会输出一个网址,您可以访问该网址以查看或测试您的 Firebase 托管内容和 HTTP 函数。

部署

创建函数并设置重写规则后,您将需要部署 Firebase 项目。在终端运行以下命令。

firebase deploy

部署后,您会注意到,您的函数通常可通过以下网址访问:

https://us-central1-<your-project-id>.cloudfunctions.net/bigben

与重写规则中指定的路径匹配的 Firebase 托管网站上的所有流量将被代理到相应的函数。

体验示例函数

部署完成后,您可以在 Firebase 托管网站上转到 /bigben,以便查看其运行中的状态。

https://<your-project-id>.firebaseapp.com/bigben

使用 Cookie

将 Firebase 托管与 Cloud Functions 搭配使用时,Cookie 通常会从传入的请求中剥离出来。这是实现高效的 CDN 缓存行为所必需的。只有特别指定的 __session Cookie 可以传入到函数执行过程中。

__session Cookie(如果存在)会自动成为缓存键的一部分,也就是说,使用不同 Cookie 的两位用户绝不会收到彼此的已缓存响应。只有在您的函数根据用户授权提供不同的内容时,您才应当使用 __session Cookie。

管理缓存行为

Firebase 托管使用强大的全球内容分发网络 (CDN),使您的网站尽可能快。Firebase 托管上的静态内容将被缓存,直到部署新版本为止。由于函数将动态生成内容,因此函数处理的请求默认不会缓存在 CDN 中。您可以自行配置缓存行为,使应用速度加快并降低函数执行成本。

设置 Cache-Control

用于管理缓存的主要工具是 Cache-Control 标头。设置此内容后,您可以与浏览器和 CDN 进行通信,设定内容缓存的时间。在函数中设置 Cache-Control 的方式如下所示:

res.set('Cache-Control', 'public, max-age=300, s-maxage=600');

上述标头执行以下三个操作:

  • 将缓存标记为公开。这意味着此内容可以被中间服务器缓存(在本例中为 CDN)。默认情况下,Cache-Control 设置为私密,这意味着仅允许用户的浏览器缓存它。
  • 告知浏览器可以使用 max-age 缓存内容的秒数。在上例中,我们告知浏览器缓存五分钟。
  • 告知 CDN 可以使用 s-maxage 缓存内容的秒数。在上例中,我们告知 CDN 缓存十分钟。

设置最长存在时间时,您应该将其设置为允许用户收到过期内容的最长时间。如果页面每几秒更改一次,此值将是一个较小的数字。但其他内容可以安全地缓存数小时、数天甚至数月。

您可以在 Mozilla 开发者网络上了解有关 Cache-Control 标头的更多信息。

何时提供缓存的内容?

如果您设置了公共 Cache-Control 标头,则您的内容将基于以下元素在 CDN 中缓存:

  • 主机名
  • 路径
  • 查询字符串
  • 在 Vary 中指定的标头的内容

Vary 标头是指您可以如何发送信号以说明请求的哪些部分对于确定您的响应很重要。大多数时候,你无需担心此问题。Firebase 托管会自动确保在通常情况下对您的响应设置适当的 Vary 标头。这包括确保您正在使用的任何会话 Cookie 或授权标头是缓存键的一部分,以防意外泄露内容。

在某些高级用例中,您可能需要其他标头来影响缓存。在这种情况下,您可以只在响应中设置 Vary 标头:

res.set('Vary', 'Accept-Encoding, X-My-Custom-Header');

现在,另外两个具有不同 X-My-Custom-Header 标头的相同请求将分别被缓存。

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面