Naar console

配置托管行为

通过 Firebase 托管,您可以配置自定义托管行为,包括自定义错误页面重定向重写标头。您还可以指定要将哪些文件从您的项目目录部署到 Firebase 项目。

firebase.json 文件中定义您的 Firebase 托管配置。

在项目的根目录中找到您的 firebase.json 文件。当您运行 firebase init 命令时,Firebase 会自动创建 firebase.json 文件。

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

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

托管响应的优先级顺序

本页介绍的不同 Firebase 托管配置选项有时可能会重叠。如果有冲突,托管会按照以下优先级顺序确定其响应:

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

指定要部署的文件

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

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

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

public

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

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

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

  // ...
}

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

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

  // ...
}

ignore

可选
ignore 属性用于指定在部署时要忽略的文件。它可以处理 glob 模式,所采用的方式与 Git 处理 .gitignore 的方式一样。

以下是要忽略的文件的默认值:

"hosting": {
  // ...

  "ignore": [
    "firebase.json",  // the Firebase configuration file (this file)
    "**/.*",  // 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/Not Found 页面

可选
当用户尝试访问的页面不存在时,您可以显示自定义 404 Not Found 错误。

在项目的 public 目录中创建一个新文件,将其命名为 404.html,然后在该文件中添加自定义的 404 Not Found 内容。

如果浏览器在您的网域或子网域上触发 404 Not Found 错误,Firebase 托管将显示该自定义 404.html 页面的内容。

配置重定向

可选
使用网址重定向可防止在页面移动后出现损坏的链接,还可以缩短网址。例如,您可以将浏览器从 example.com/team 重定向至 example.com/about.html

firebase.json 文件的 hosting 中添加一个 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
  } ]
}

redirects 属性包含一系列重定向规则,其中每个规则必须包含以下各项:

  • source,用于指定 glob 模式

  • destination,这是静态网址,可以是相对路径,也可以是绝对路径

  • type,用于指定 HTTP 响应代码

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

最后,type 值指定提供的具体 HTTP 响应代码,可以是 301(对应于“已永久移动”)或 302(对应于“已找到”(临时重定向))。

捕获重定向的网址段

可选
有时,您可能需要捕获重定向 source 网址的特定网址段,然后在重定向 destination 网址中重复使用这些网址段。

您可以添加 : 前缀来标识网址段,从而捕获这些网址段。如果您还需要捕获网址段后面的其余网址路径,请紧跟在网址段后面添加一个 *。例如:

"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 caputured by the "source" value
    "type": 301
  } ]
}

配置重写

可选
如果要为多个网址显示同样的内容,则可以使用重写。重写在与模式匹配结合使用时尤其有用,因为您可以接受与模式匹配的任何网址,让客户端代码来决定要显示的内容。

您还可以使用重写来支持使用 HTML5 pushState 进行导航的应用。当浏览器尝试打开指定的 source 网址时,将获得 destination 网址中文件的内容。

firebase.json 文件的 hosting 中添加一个 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"
  }, {
    // Excludes specified pathways from rewrites
    "source": "!/@(js|css)/**",
    "destination": "/index.html"
  } ]
}

rewrites 属性包含一系列重写规则,其中每个规则必须包含以下各项:

  • source,用于指定 glob 模式

  • destination,这是必须存在的本地文件

仅当指定的 source 中不存在文件或目录时,Firebase 托管才会应用重写规则。触发规则时,浏览器会返回指定 destination 文件的实际内容,而非 HTTP 重定向的内容。

将请求定向到函数

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

例如,要定向您的托管网站上的 /bigben 页面收到的所有请求以执行 bigben 函数,请运行以下命令:

"hosting": {
  // ...

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

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

  • 您的 Firebase 子网域:projectID.web.app/bigbenprojectID.firebaseapp.com/bigben

  • 任何已关联的自定义网域custom-domain/bigben

将请求定向到 Cloud Run 容器

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

例如,要定向您的托管网站上的 /helloworld 页面收到的所有请求以触发 helloworld 容器实例的启动和运行,请运行以下命令:

"hosting": {
 // ...

 // Add the "rewrites" attribute within "hosting"
 "rewrites": [ {
   "source": "/helloworld",
   "run": {
     "serviceId": "helloworld",  // "service name" (from when you <a href="#deploy">deployed the container image)</a>
     "region": "us-central1"     // optional (if omitted, default is us-central1)
   }
 } ]
}

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

  • 您的 Firebase 子网域:projectID.web.app/helloworldprojectID.firebaseapp.com/helloworld

  • 任何已关联的自定义网域custom-domain/helloworld

您可以使用 rewrites 创建自定义网域动态链接。如需详细了解如何为动态链接设置自定义网域,请访问动态链接文档。

例如,您可以执行以下操作:

  • 将您的网域仅用于动态链接:

    "hosting": {
      // ...
    
      "appAssociation": "AUTO",  // required for Dynamic Links (default is AUTO if not specified)
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/**",  // Dynamic Links start with "https://<your-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/**",  // Dynamic Links can start with "https://<your-domain>/promos/"
        "dynamicLinks": true
      }, {
        "source": "/links/share/**",  // Dynamic Links can start with "https://<your-domain>/links/share/"
        "dynamicLinks": true
      } ]
    }
    

若要在 firebase.json 文件中配置动态链接,需要进行如下设置:

  • appAssociation 属性设置为 AUTO

    • 如果您的配置中不包含该属性,则 appAssociation 的默认值为 AUTO
    • 将该属性设置为 AUTO 后,托管会在收到请求时动态生成 assetlinks.jsonapple-app-site-association 文件。
  • 动态链接的 rewrites 属性,包含一系列重写规则,其中每个规则必须包含以下各项:

    • source,指定要用于动态链接的路径

      • 与将路径重写为网址的规则不同,动态链接重写规则不能包含正则表达式。
    • dynamicLinks 属性设置为 true

配置标头

可选
通过标头,客户端和服务器可传递其他信息以及请求或响应。一些标头集可能会影响浏览器处理页面及其内容的方式,包括访问权限控制、身份验证、缓存和编码。

firebase.json 文件的 hosting 中添加一个 headers 属性,即可指定文件专属的自定义响应标头。例如:

"hosting": {
  // ...

  // Add the "headers" attribute within "hosting"
  "headers": [ {
    // Specifies a CORS header for all font files
    "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
    "headers": [ {
      "key": "Access-Control-Allow-Origin",
      "value": "*"
    } ]
  }, {
    // Overrides the default 1 hour browser cache with a 2 hour cache for all image files
    "source": "**/*.@(jpg|jpeg|gif|png)",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=7200"
    } ]
  }, {
    // Sets the cache header for 404 pages to cache for 5 minutes
    "source": "404.html",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=300"
    } ]
  } ]
}

headers 属性包含一系列定义,其中每个定义必须包含以下各项:

  • 一个 source 值,托管会将该值与原始请求路径匹配,而不考虑任何重写规则

  • 托管应用于请求路径的一系列(子)headers,每个子标头数组必须包括指定的 keyvalue

如需详细了解 Cache-Control,请参阅介绍提供动态内容和托管微服务的“托管”部分。

您还可以详细了解 CORS 标头。

控制 .html 扩展名

可选
通过 cleanUrls 属性,您可以控制网址是否应包含 .html 扩展名。

如果值为 true,托管会从已上传的文件网址中自动删除 .html 扩展名。如果在请求中添加 .html 扩展名,托管会执行 301 重定向,以重定向至相同路径,但会删除 .html 扩展名。

firebase.json 文件的 hosting 中添加一个 cleanUrls 属性,即可指定添加 .html 扩展名。例如:

"hosting": {
  // ...

  // Add the "cleanUrls" attribute within "hosting"
  "cleanUrls": true
}

控制尾部斜杠

可选
通过 trailingSlash 属性,您可以控制网址的末尾是否应带有斜杠。

  • 如果为 true,托管会重定向网址以便在末尾处添加斜杠。
  • 如果为 false,托管会重定向网址以移除末尾处的斜杠。
  • 若不指定,则托管将仅对目录索引文件使用尾部斜杠(例如 about/index.html)。

firebase.json 文件的 hosting 中添加一个 trailingSlash 属性,即可指定添加结尾斜杠。例如:

"hosting": {
  // ...

  // Add the "trailingSlash" attribute within "hosting"
  "trailingSlash": false
}

Glob 模式匹配

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",

  }
}