配置托管行为
借助 Firebase Hosting,您可以为网站请求配置自定义托管行为。
可以为 Hosting 配置哪些内容?
- 在本地项目目录中指定要部署到 Firebase Hosting 的文件。了解具体方法。
- 提供自定义的“404/未找到”页面。了解具体方法。
- 为您已移动或已删除的页面设置
redirects。了解具体方法。 -
为以下目的设置
rewrites: -
为多个网址显示相同的内容。了解具体方法。
- 通过 Hosting 网址提供函数或访问 Cloud Run 容器。了解提供函数或访问容器的具体方法。
- 创建自定义网域 Dynamic Link。了解具体方法。
- 添加
headers以传递有关请求或响应的额外信息,例如浏览器应如何处理页面及其内容(身份验证、缓存、编码等等)。了解具体方法。 - 设置国际化 (i18n) 重写以根据用户的语言偏好和/或国家/地区提供特定内容。了解具体方法(不同页面)。
在何处定义 Hosting 配置?
可以在 firebase.json 文件中定义 Firebase Hosting 配置。当您运行 firebase init 命令时,Firebase 会自动在项目的根目录中创建 firebase.json 文件。
您可以在本页底部找到完整的 firebase.json 配置示例(仅涵盖 Firebase Hosting)。请注意,firebase.json 文件也可以包含其他 Firebase 服务的配置。
您可以使用 Hosting REST API 检查已部署的 firebase.json 内容。
Hosting 响应的优先级顺序
本页介绍的不同 Firebase Hosting 配置选项有时可能会重叠。如果有冲突,Hosting 会按照以下优先级顺序确定应如何响应:
- 以
/__/*路径段开头的预留命名空间 - 已配置的重定向
- 完全匹配的静态内容
- 配置的重写
- 自定义 404 页面
- 默认的 404 页面
如果使用 i18n 重写,则完全匹配和 404 处理优先级顺序会在范围内扩展,以适应“i18n content”。
指定要部署的文件
默认 firebase.json 文件中包含的默认属性 public 和 ignore 定义了应将项目目录中的哪些文件部署到您的 Firebase 项目。
firebase.json 文件中的默认 hosting 配置如下所示:
"hosting": {
"public": "public", // the only required attribute for Hosting
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
公开
必需
public 属性指定要部署到 Firebase Hosting 的目录。默认值是名为 public 的目录,但您可以指定任何目录的路径,只要项目目录中存在该路径即可。
以下是要部署的目录的默认指定名称:
"hosting": {
"public": "public"
// ...
}
您可以将默认值更改为您想要部署的目录:
"hosting": {
"public": "dist/app"
// ...
}
ignore
可选
ignore 属性指定在部署时要忽略的文件。它可以使用 glob,与 Git 处理 .gitignore 的方式一样。
以下是要忽略的文件的默认值:
"hosting": {
// ...
"ignore": [
"firebase.json", // the Firebase configuration file (the file described on this page)
"**/.*", // files with a leading period should be hidden from the system
"**/node_modules/**" // contains dependencies used to create your site but not run it
]
}
自定义“404/未找到”页面
可选
当用户尝试访问的页面不存在时,您可以显示自定义 404 Not Found 错误。
在项目的 public 目录中创建一个新文件,将其命名为 404.html,然后在该文件中添加自定义的 404 Not Found 内容。
如果浏览器在您的网域或子网域上触发 404 Not Found 错误,Firebase Hosting 将显示该自定义 404.html 页面的内容。
配置重定向
可选
使用网址重定向可防止在页面转移后出现损坏的链接,还可以缩短网址。例如,您可以将浏览器从 example.com/team 重定向至 example.com/about.html。
通过创建包含一系列对象(称为“重定向规则”)的 redirects 属性来指定网址重定向。在每条规则中指定一个网址格式,如果该网址格式与请求网址路径相匹配,则会触发 Hosting 做出重定向到指定目标网址的响应。
以下是 redirects 属性的基本结构。此示例通过向 /bar 发出新请求来将请求重定向到 /foo。
"hosting": {
// ...
// Returns a permanent redirect to "/bar" for requests to "/foo" (but not "/foo/**")
"redirects": [ {
"source": "/foo",
"destination": "/bar",
"type": 301
} ]
}
查看 redirects 属性的详细示例
"hosting": {
// ...
// Add the "redirects" attribute within "hosting"
"redirects": [ {
// Returns a permanent redirect to "/bar" for requests to "/foo" (but not "/foo/**")
"source": "/foo",
"destination": "/bar",
"type": 301
}, {
// Returns a permanent redirect to "/bar" for requests to both "/foo" and "/foo/**"
"source": "/foo{,/**}"
"destination": "/bar"
"type": 301
}, {
// Returns a temporary redirect for all requests to files or directories in the "firebase" directory
"source": "/firebase/**",
"destination": "https://firebase.google.com/",
"type": 302
}, {
// A regular expression-based redirect equivalent to the above behavior
"regex": "/firebase/.*",
"destination": "https://firebase.google.com/",
"type": 302
} ]
}
redirects 属性包含一系列重定向规则,其中每条规则都必须包含下表中的字段。
Firebase Hosting 会在开始处理每个请求时(在浏览器确定该路径中是否存在文件或文件夹之前),将 source 或 regex 值与所有网址路径进行比较。如果找到匹配项,Firebase Hosting 源服务器会发送 HTTPS 重定向响应,告知浏览器向 destination 网址发出新请求。
| 字段 | 说明 | |
|---|---|---|
redirects |
||
source(推荐) 或 regex |
一个网址格式,如果该格式与初始请求网址匹配,则会触发 Hosting 应用重定向 - 使用 source 可指定 glob(推荐)。 - 使用 regex 可指定 RE2 正则表达式。 |
|
destination |
浏览器应向其发出新请求的静态网址 此网址可以是相对路径,也可以是绝对路径。 | |
type |
HTTPS 响应代码 - 使用 301 类型表示“永久移动” - 使用 302 类型表示“发现”(临时重定向) |
捕获重定向的网址段
可选
有时,您可能需要捕获重定向规则网址格式(source 或 regex 值)的特定网址段,然后在该规则的 destination 路径中重复使用这些网址段。
在使用 glob 时捕获网址段
如果您使用的是 source 字段(即为您的网址格式指定 glob),则可以通过添加 : 前缀标识网址段的方式来捕获网址段。如果您还需要捕获网址段后面的其余网址路径,请紧接网址段后面添加一个 *。例如:
"hosting": {
// ...
"redirects": [ {
"source": "/blog/:post*", // captures the entire URL segment beginning at "post"
"destination": "https://blog.myapp.com/:post", // includes the entire URL segment identified and captured by the "source" value
"type": 301
}, {
"source": "/users/:id/profile", // captures only the URL segment "id", but nothing following
"destination": "/users/:id/newProfile", // includes the URL segment identified and captured by the "source" value
"type": 301
} ]
}
在使用 RE2 正则表达式时捕获网址段
如果您使用的是 regex 字段(即为您的网址格式指定 RE2 正则表达式),则可以使用已命名或未命名的 RE2 捕获组来捕获网址段。在带有 : 前缀的 destination 字段中可以使用已命名的捕获组,通过 regex 值中的相应数值索引(索引编号从 1 开始)可以引用未命名的捕获组。例如:
"hosting": {
// ...
"redirects": [ {
"regex": "/blog/(?P<post>.+)", // if you're familiar with PCRE, be aware that RE2 requires named capture groups to begin with ?P
"destination": "https://blog.myapp.com/:post", // includes the entire URL segment identified and captured by the `regex` value
"type": 301
}, {
"regex": "/users/(\d+)/profile", // uses the \d directive to only match numerical path segments
"destination": "/users/:1/newProfile", // the first capture group to be seen in the `regex` value is named 1, and so on
"type": 301
} ]
}
配置重写
可选 使用重写可以为多个网址显示相同的内容。重写在与模式匹配结合使用时尤其有用,因为您可以接受与模式匹配的任何网址,让客户端代码来决定要显示的内容。
您还可以使用重写来支持使用 HTML5 pushState 进行导航的应用。当某浏览器尝试打开与指定的 source 或 regex 网址格式匹配的网址路径时,浏览器会改为获取 destination 网址中文件的内容。
通过创建包含一系列对象(称为“重写规则”)的 rewrites 属性来指定网址重写。在每条规则中指定一个网址格式,如果该网址格式与请求网址路径相匹配,则会触发 Hosting 进行响应,其行为就像是已为服务提供了指定的目标网址。
以下是 rewrites 属性的基本结构。此示例为访问不存在的文件或目录的请求提供 index.html。
"hosting": {
// ...
// Serves index.html for requests to files or directories that do not exist
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
}
查看 rewrites 属性的详细示例
"hosting": {
// ...
// Add the "rewrites" attribute within "hosting"
"rewrites": [ {
// Serves index.html for requests to files or directories that do not exist
"source": "**",
"destination": "/index.html"
}, {
// Serves index.html for requests to both "/foo" and "/foo/**"
// Using "/foo/**" only matches paths like "/foo/xyz", but not "/foo"
"source": "/foo{,/**}",
"destination": "/index.html"
}, {
// A regular expression-based rewrite equivalent to the above behavior
"regex": "/foo(/.*)?",
"destination": "/index.html"
}, {
// Excludes specified pathways from rewrites
"source": "!/@(js|css)/**",
"destination": "/index.html"
} ]
}
rewrites 属性包含一系列重写规则,其中每条规则都必须包含下表中的字段。
仅当与指定的 source 或 regex 网址格式匹配的网址路径中不存在文件或目录时,Firebase Hosting 才会采用重写规则。当请求触发重写规则时,浏览器会返回指定 destination 文件的实际内容,而不是 HTTP 重定向。
| 字段 | 说明 | |
|---|---|---|
rewrites |
||
source(推荐) 或 regex |
一个网址格式,如果该格式与初始请求网址匹配,则会触发 Hosting 采用重写 - 使用 source 可指定 glob(推荐)。 - 使用 regex 可指定 RE2 正则表达式。 |
|
destination |
必须存在的本地文件 此网址可以是相对路径,也可以是绝对路径。 |
将请求定向到函数
您可以使用 rewrites 从 Firebase Hosting 网址提供函数。以下示例摘自使用 Cloud Functions 提供动态内容。
例如,如需定向来自您的 Hosting 网站上 /bigben 页面的所有请求以执行 bigben 函数,请使用以下代码:
"hosting": {
// ...
// Directs all requests from the page `/bigben` to execute the `bigben` function
"rewrites": [ {
"source": "/bigben",
"function": {
"functionId": "bigben",
"region": "us-central1" // optional (see note below)
"pinTag": true // optional (see note below)
}
} ]
}
function 块中的 region 的作用方式
如果
hosting.rewrites配置的function块中省略了region,Firebase CLI 会尝试根据函数的源代码自动检测区域;如果源代码中也未指定区域,则默认为us-central1。如果函数的源代码不可用,CLI 会尝试通过已部署的函数检测区域。如果函数在多个区域中使用,则必须在hosting.rewrites配置中指定region,这样 CLI 才能确定具体区域。
function 块中的 pinTag 的作用方式
pinTag功能仅在 Cloud Functions for Firebase(第 2 代)中提供。借助此功能,您可以确保用于生成网站动态内容的每个函数都与您的静态 Hosting 资源和 Hosting 配置保持同步。此外,您还可以利用此功能通过 Hosting 预览渠道预览对函数的重写。如果您在
hosting.rewrites配置的function块中添加了"pinTag": true,则“固定的”函数将与您的静态 Hosting 资源和配置一起部署,即使运行firebase deploy --only hosting命令也是如此。如果您回滚网站的某个版本,“固定的”函数也会相应回滚。此功能依赖于 Cloud Run 标记并且有相应的配额限制,即每个服务不超过 1,000 个标记,每个区域不超过 2,000 个标记。这意味着,在进行数百次部署后,网站最早的一些版本可能会停止运行。
添加此重写规则并部署到 Firebase(使用 firebase deploy)后,便可通过以下网址访问您的函数:
- 您的 Firebase 子网域:
PROJECT_ID.web.app/bigben和PROJECT_ID.firebaseapp.com/bigben - 任何关联的自定义网域:
CUSTOM_DOMAIN/bigben
当 Firebase Hosting 将流量转发到函数时,该函数会接收完整的原始请求路径和查询字符串。例如,对 Hosting 网站上 /bigben/hello/world?foo=bar 的请求会传递给函数,且完整路径和查询字符串保持不变。请确保您的函数处理程序能够处理整个绝对网址,而不仅仅是重写规则中定义的基本路径。
使用 Hosting 将请求重定向到函数时,支持的 HTTP 请求方法有:GET、POST、HEAD、PUT、DELETE、PATCH 和 OPTIONS。不支持 REPORT 或 PROFIND 等其他方法。
将请求定向到 Cloud Run 容器
您可以使用 rewrites 从 Firebase Hosting 网址访问 Cloud Run 容器。以下示例摘自使用 Cloud Run 提供动态内容。
例如,如需定向来自您 Hosting 网站上 /helloworld 页面的所有请求以触发 helloworld 容器实例的启动和运行,请使用以下代码:
"hosting": {
// ...
// Directs all requests from the page `/helloworld` to trigger and run a `helloworld` container
"rewrites": [ {
"source": "/helloworld",
"run": {
"serviceId": "helloworld", // "service name" (from when you deployed the container image)
"region": "us-central1" // optional (if omitted, default is us-central1)
}
} ]
}
run 块中的 pinTag 的作用方式
借助此功能,您可以确保用于生成网站动态内容的 Cloud Run 服务的修订版本与您的静态 Hosting 资源和 Hosting 配置保持同步。此外,您还可以利用此功能通过 Hosting 预览渠道预览对 Cloud Run 的重写。
如果您在
hosting.rewrites配置的run块中添加了"pinTag": true,系统会在部署时将静态 Hosting 资源和配置固定到 Cloud Run 服务的最新修订版本。如果您回滚网站的某个版本,“固定的”Cloud Run 服务的修订版本也会相应回滚。此功能依赖于 Cloud Run 标记并且有相应的配额限制,即每个服务不超过 1,000 个标记,每个区域不超过 2,000 个标记。这意味着,在进行数百次部署后,网站最早的一些版本可能会停止运行。
添加此重写规则并部署到 Firebase(使用 firebase deploy)后,便可通过以下网址访问您的容器映像:
- 您的 Firebase 子网域:
PROJECT_ID.web.app/helloworld和PROJECT_ID.firebaseapp.com/helloworld - 任何关联的自定义网域:
CUSTOM_DOMAIN/helloworld
使用 Hosting 将请求重定向到 Cloud Run 容器时,支持的 HTTP 请求方法有:GET、POST、HEAD、PUT、DELETE、PATCH 和 OPTIONS。不支持 REPORT 或 PROFIND 等其他方法。
为获得最佳性能,请使用以下区域将您的 Cloud Run 服务与 Hosting 共置:
us-west1us-central1us-east1europe-west1asia-east1
以下区域支持从 Hosting 重写到 Cloud Run:
asia-east1asia-east2asia-northeast1asia-northeast2asia-northeast3asia-south1asia-south2asia-southeast1asia-southeast2australia-southeast1australia-southeast2europe-central2europe-north1europe-southwest1europe-west1europe-west12europe-west2europe-west3europe-west4europe-west6europe-west8europe-west9me-central1me-west1northamerica-northeast1northamerica-northeast2southamerica-east1southamerica-west1us-central1us-east1us-east4us-east5us-south1us-west1us-west2us-west3us-west4us-west1us-central1us-east1europe-west1asia-east1
