获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

配置托管行为

借助 Firebase 托管,您可以为对您网站的请求配置自定义托管行为。

您可以为托管配置什么?

  • 指定要部署到 Firebase 托管的本地项目目录中的哪些文件。学习怎样。

  • 提供定制的 404/未找到页面。学习怎样。

  • 为您已移动或删除的页面设置redirects学习怎样。

  • 为以下任何目的设置rewrites

  • 添加headers以传递有关请求或响应的其他信息,例如浏览器应如何处理页面及其内容(身份验证、缓存、编码等)。学习怎样。

  • 设置国际化 (i18n) 重写以根据用户的语言偏好和/或国家/地区提供特定内容。了解如何(不同的页面)。

您在哪里定义托管配置?

您可以在firebase.json文件中定义 Firebase 托管配置。当您运行firebase init命令时,Firebase 会自动在项目目录的根目录中创建您的firebase.json文件。

您可以在本页底部找到完整的firebase.json配置示例(仅涵盖 Firebase 托管)。请注意, firebase.json文件还可以包含其他 Firebase 服务的配置

您可以使用Hosting REST API检查部署的firebase.json内容。

托管响应的优先顺序

此页面上描述的不同 Firebase 托管配置选项有时可能会重叠。如果存在冲突,Hosting 将使用以下优先级顺序确定其响应:

  1. /__/*路径段开头的保留命名空间
  2. 配置的重定向
  3. 完全匹配的静态内容
  4. 配置的重写
  5. 自定义 404页面
  6. 默认 404 页面

如果您使用i18n rewrites ,则完全匹配和 404 处理优先级顺序的范围会扩大以适应您的“i18n 内容”。

指定要部署的文件

默认的firebase.json文件中包含的默认属性( publicignore )定义了项目目录中的哪些文件应该部署到 Firebase 项目中。

firebase.json文件中的默认hosting配置如下所示:

"hosting": {
  "public": "public",  // the only required attribute for Hosting
  "ignore": [
    "firebase.json",
    "**/.*",
    "**/node_modules/**"
  ]
}

上市

必需的
public属性指定要部署到 Firebase 托管的目录。默认值为名为public的目录,但您可以指定任何目录的路径,只要它存在于您的项目目录中。

以下是要部署的目录的默认指定名称:

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

  // ...
}

您可以将默认值更改为要部署的目录:

"hosting": {
  "public": "dist/app"

  // ...
}

忽视

可选的
ignore属性指定部署时要忽略的文件。它可以像Git处理.gitignore一样使用.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 托管将显示此自定义404.html页面的内容。

配置重定向

可选的
如果您移动页面或缩短 URL,请使用 URL 重定向来防止链接断开。例如,您可以将浏览器从example.com/team重定向到example.com/about.html

通过创建包含对象数组(称为“重定向规则”)的redirects属性来指定 URL 重定向。在每个规则中,指定一个 URL 模式,如果与请求 URL 路径匹配,则会触发 Hosting 以重定向到指定目标 URL 进行响应。

这是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属性包含一个重定向规则数组,其中每个规则必须包含下表中的字段。

Firebase 托管在每个请求开始时(在浏览器确定该路径中是否存在文件或文件夹之前)将sourceregex值与所有 URL 路径进行比较。如果找到匹配项,则 Firebase 托管源服务器会发送 HTTPS 重定向响应,告诉浏览器在destination URL 处发出新请求。

场地描述
redirects
source (推荐)
regex

一种 URL 模式,如果与初始请求 URL 匹配,则会触发 Hosting 应用重定向

destination

浏览器应发出新请求的静态 URL

此 URL 可以是相对路径或绝对路径。

type

HTTPS 响应代码

  • 为“永久移动”使用301类型
  • 为“找到”使用302类型(临时重定向)

捕获重定向的 URL 段

可选的
有时,您可能需要捕获重定向规则的 URL 模式( sourceregex值)的特定段,然后在规则的destination路径中重新使用这些段。

配置重写

可选的
使用重写来为多个 URL 显示相同的内容。重写对于模式匹配特别有用,因为您可以接受任何与模式匹配的 URL,并让客户端代码决定要显示的内容。

您还可以使用重写来支持使用HTML5 pushState进行导航的应用程序。当浏览器尝试打开与指定sourceregex URL 模式匹配的 URL 路径时,浏览器将获得destination URL 处的文件内容。

通过创建包含对象数组(称为“重写规则”)的rewrites属性来指定 URL 重写。在每个规则中,指定一个 URL 模式,如果该模式与请求 URL 路径匹配,则会触发 Hosting 响应,就好像为服务提供了指定的目标 URL。

这是rewrites属性的基本结构。此示例为对不存在的文件或目录的请求提供index.html

"hosting": {
  // ...

  // Serves index.html for requests to files or directories that do not exist
  "rewrites": [ {
    "source": "**",
    "destination": "/index.html"
  } ]
}

rewrites属性包含一个重写规则数组,其中每个规则必须包含下表中的字段。

Firebase 托管仅在与指定sourceregex URL 模式匹配的 URL 路径中不存在文件或目录时应用重写规则。当请求触发重写规则时,浏览器会返回指定destination文件的实际内容,而不是 HTTP 重定向。

场地描述
rewrites
source (推荐)
regex

一个 URL 模式,如果与初始请求 URL 匹配,则会触发 Hosting 应用重写

destination

必须存在的本地文件

此 URL 可以是相对路径或绝对路径。

直接请求函数

您可以使用rewrites从 Firebase 托管 URL 提供函数。以下示例摘自使用 Cloud Functions 提供动态内容

例如,要引导来自您主机站点上/bigben页面的所有请求以执行bigben功能:

"hosting": {
  // ...

  // Directs all requests from the page `/bigben` to execute the `bigben` function
  "rewrites": [ {
    "source": "/bigben",
    "function": "bigben",
    "region": "us-central1"  // optional (see note below)
  } ]
}

添加此重写规则并部署到 Firebase(使用firebase deploy )后,可以通过以下 URL 访问您的函数:

  • 您的 Firebase 子域:
    PROJECT_ID .web.app/bigbenPROJECT_ID .firebaseapp.com/bigben

  • 任何连接的自定义域
    CUSTOM_DOMAIN /bigben

当使用 Hosting 将请求重定向到函数时,支持的 HTTP 请求方法是GETPOSTHEADPUTDELETEPATCHOPTIONS 。不支持REPORTPROFIND等其他方法。

将请求定向到 Cloud Run 容器

您可以使用rewrites从 Firebase 托管 URL 访问 Cloud Run 容器。以下示例摘自使用 Cloud Run 提供动态内容

例如,要引导来自主机站点上/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)
   }
 } ]
}

添加此重写规则并部署到 Firebase(使用firebase deploy )后,您的容器映像可通过以下 URL 访问:

  • 您的 Firebase 子域:
    PROJECT_ID .web.app/helloworldPROJECT_ID .firebaseapp.com/helloworld

  • 任何连接的自定义域
    CUSTOM_DOMAIN /helloworld

使用 Hosting 将请求重定向到 Cloud Run 容器时,支持的 HTTP 请求方法有GETPOSTHEADPUTDELETEPATCHOPTIONS 。不支持REPORTPROFIND等其他方法。

目前,您可以在以下区域将 Cloud Run 重写与托管一起使用:

  • asia-east1
  • asia-east2
  • asia-northeast1
  • asia-northeast2
  • asia-northeast3
  • asia-south1
  • asia-southeast1
  • asia-southeast2
  • australia-southeast1
  • europe-north1
  • europe-west1
  • europe-west2
  • europe-west3
  • europe-west4
  • europe-west6
  • northamerica-northeast1
  • southamerica-east1
  • us-central1
  • us-east1
  • us-east4
  • us-west1

您可以使用rewrites来创建自定义域动态链接。有关为动态链接设置自定义域的详细信息,请访问动态链接文档。

  • 将您的自定义域用于动态链接

    "hosting": {
      // ...
    
      "appAssociation": "AUTO",  // required for Dynamic Links (default is AUTO if not specified)
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/**",  // the Dynamic Links start with "https://CUSTOM_DOMAIN/"
        "dynamicLinks": true
      } ]
    }
    
  • 指定用于动态链接的自定义域路径前缀

    "hosting": {
      // ...
    
      "appAssociation": "AUTO",  // required for Dynamic Links (default is AUTO if not specified)
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/promos/**",  // the Dynamic Links start with "https://CUSTOM_DOMAIN/promos/"
        "dynamicLinks": true
      }, {
        "source": "/links/share/**",  // the Dynamic Links start with "https://CUSTOM_DOMAIN/links/share/"
        "dynamicLinks": true
      } ]
    }
    

firebase.json文件中配置动态链接需要以下内容:

场地描述
appAssociation

必须设置为AUTO

  • 如果您未在配置中包含此属性,则appAssociation的默认值为AUTO
  • 通过将此属性设置为AUTO ,Hosting 可以在请求时动态生成assetlinks.jsonapple-app-site-association文件。
rewrites
source

您要用于动态链接的路径

与重写 URL 路径的规则不同,动态链接的重写规则不能包含正则表达式。

dynamicLinks必须设置为true

配置标头

可选的
标头允许客户端和服务器将附加信息与请求或响应一起传递。某些标头集会影响浏览器处理页面及其内容的方式,包括访问控制、身份验证、缓存和编码。

通过创建包含标头对象数组的标headers属性来指定自定义的、特定于文件的响应标头。在每个对象中,指定一个 URL 模式,如果与请求 URL 路径匹配,则会触发 Hosting 应用指定的自定义响应标头。

这是headers属性的基本结构。此示例为所有字体文件应用 CORS 标头。

"hosting": {
  // ...

  // Applies a CORS header for all font files
  "headers": [ {
    "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
    "headers": [ {
      "key": "Access-Control-Allow-Origin",
      "value": "*"
    } ]
  } ]
}

headers属性包含一个定义数组,其中每个定义必须包含下表中的字段。

场地描述
headers
source (推荐)
regex

一个 URL 模式,如果与初始请求 URL 匹配,则会触发 Hosting 应用自定义标头

要创建与您的自定义 404 页面匹配的标题,请使用404.html作为您的sourceregex值。

(子) headers数组

Hosting 应用于请求路径的自定义标头

每个子标题必须包含一个key value (请参阅接下来的两行)。

key标头的名称,例如Cache-Control
value标头的值,例如max-age=7200

您可以在描述提供动态内容和托管微服务的托管部分中了解有关Cache-Control的更多信息。您还可以了解有关CORS标头的更多信息。

控制.html扩展名

可选的
cleanUrls属性允许您控制 URL 是否应包含.html扩展名。

当为true时,Hosting 会自动从上传的文件 URL 中删除.html扩展名。如果在请求中添加了.html扩展名,Hosting 会执行301重定向到同一路径,但会删除.html扩展名。

以下是通过包含cleanUrls属性来控制在 URL 中包含.html的方法:

"hosting": {
  // ...

  // Drops `.html` from uploaded URLs
  "cleanUrls": true
}

控制尾部斜杠

可选的
trailingSlash属性允许您控制静态内容 URL 是否应包含尾部斜杠。

  • 当为true时,Hosting 会重定向 URL 以添加尾部斜杠。
  • 当为false时,Hosting 会重定向 URL 以删除尾部斜杠。
  • 如果未指定,Hosting 仅对目录索引文件使用尾部斜杠(例如, about/index.html )。

以下是如何通过添加trailingSlash属性来控制尾部斜杠:

"hosting": {
  // ...

  // Removes trailing slashes from URLs
  "trailingSlash": false
}

trailingSlash属性不影响对 Cloud Functions 或 Cloud Run 提供的动态内容的重写。

全局模式匹配

Firebase 托管配置选项在 extglob 中广泛使用glob 模式匹配表示法,类似于 Git 处理gitignore规则和Bower处理ignore规则的方式。此 wiki 页面是更详细的参考,但以下是此页面上使用的示例的说明:

  • firebase.json — 只匹配public目录根目录下的firebase.json文件

  • ** — 匹配任意子目录中的任何文件或文件夹

  • * — 仅匹配public目录根目录中的文件和文件夹

  • **/.* - 匹配任何以 . 开头的文件. (通常是隐藏文件,如.git文件夹中)在任意子目录中

  • **/node_modules/** — 匹配node_modules文件夹的任意子目录中的任何文件或文件夹,该文件夹本身可以位于public目录的任意子目录中

  • **/*.@(jpg|jpeg|gif|png) - 匹配任意子目录中的任何文件,该文件恰好以下列之一结尾: .jpg.jpeg.gif.png

完整托管配置示例

以下是 Firebase 托管的完整firebase.json配置示例。请注意, firebase.json文件还可以包含其他 Firebase 服务的配置

{
  "hosting": {

    "public": "dist/app",  // "public" is the only required attribute for Hosting

    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],

    "redirects": [ {
      "source": "/foo",
      "destination": "/bar",
      "type": 301
    }, {
      "source": "/firebase/**",
      "destination": "https://www.firebase.com",
      "type": 302
    } ],

    "rewrites": [ {
      // Shows the same content for multiple URLs
      "source": "/app/**",
      "destination": "/app/index.html"
    }, {
      // Configures a custom domain for Dynamic Links
      "source": "/promos/**",
      "dynamicLinks": true
    }, {
      // Directs a request to Cloud Functions
      "source": "/bigben",
      "function": "bigben"
    }, {
      // Directs a request to a Cloud Run containerized app
      "source": "/helloworld",
      "run": {
        "serviceId": "helloworld",
        "region": "us-central1"
      }
    } ],

    "headers": [ {
      "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
      "headers": [ {
        "key": "Access-Control-Allow-Origin",
        "value": "*"
      } ]
    }, {
      "source": "**/*.@(jpg|jpeg|gif|png)",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=7200"
      } ]
    }, {
      "source": "404.html",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=300"
      } ]
    } ],

    "cleanUrls": true,

    "trailingSlash": false,

    // Required to configure custom domains for Dynamic Links
    "appAssociation": "AUTO",

  }
}