借助 Firebase 託管,您可以為網站請求配置自定義託管行為。
您可以為託管配置什麼?
指定要部署到 Firebase 託管的本地項目目錄中的哪些文件。學習如何。
提供定制的 404/Not Found 頁面。學習如何。
為您已移動或刪除的頁面設置
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 將使用以下優先級順序確定其響應:
如果您使用i18n rewrites ,則精確匹配和 404 處理優先級順序的範圍會擴展以適應您的“i18n 內容”。
指定要部署的文件
默認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
屬性指定部署時要忽略的文件。它可以像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/Not Found 頁面
選修的
當用戶嘗試訪問不存在的頁面時,您可以提供自定義的404 Not Found
錯誤。
在項目的public
目錄中創建一個新文件,將其命名為404.html
,然後將自定義的404 Not Found
內容添加到該文件中。
如果瀏覽器在您的域或子域上觸發404 Not Found
錯誤,Firebase Hosting 將顯示此自定義404.html
頁面的內容。
配置重定向
選修的
如果您移動了頁面,請使用 URL 重定向來防止鏈接損壞或縮短 URL。例如,您可以將瀏覽器從example.com/team
重定向到example.com/about.html
。
通過創建包含對像數組(稱為“重定向規則”)的redirects
屬性來指定 URL 重定向。在每個規則中,指定一個 URL 模式,如果該模式與請求 URL 路徑匹配,則觸發 Hosting 以重定向到指定的目標 URL 進行響應。
這是redirects
屬性的基本結構。此示例通過向/foo
發出新請求來將請求重定向到/bar
。
"hosting": {
// ...
// Returns a permanent redirect to "/bar" for requests to "/foo" (but not "/foo/**")
"redirects": [ {
"source": "/foo",
"destination": "/bar",
"type": 301
} ]
}
"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
值與所有 URL 路徑進行比較。如果找到匹配項,Firebase 託管源服務器會發送 HTTPS 重定向響應,告訴瀏覽器在destination
URL 發出新請求。
場地 | 描述 | |
---|---|---|
redirects | ||
source (推薦)或正則 regex | URL 模式,如果與初始請求 URL 匹配,則觸發 Hosting 應用重定向 | |
destination | 瀏覽器應在其中發出新請求的靜態 URL 此 URL 可以是相對路徑或絕對路徑。 | |
type | HTTPS 響應代碼
|
捕獲重定向的 URL 段
選修的
有時,您可能需要捕獲重定向規則的 URL 模式的特定段( source
或regex
值),然後在規則的destination
路徑中重新使用這些段。
如果您使用source
字段(即為 URL 模式指定一個 glob),則可以通過包含:
前綴來識別段來捕獲段。如果您還需要捕獲該段之後的剩餘 URL 路徑,請在該段之後立即包含一個*
。例如:
"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 } ] }
如果您使用regex
字段(即為 URL 模式指定 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 } ] }
配置重寫
選修的
使用重寫來顯示多個 URL 的相同內容。重寫對於模式匹配特別有用,因為您可以接受與模式匹配的任何 URL,並讓客戶端代碼決定顯示什麼。
您還可以使用重寫來支持使用HTML5 PushState進行導航的應用程序。當瀏覽器嘗試打開與指定source
或regex
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"
} ]
}
"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
URL 模式匹配的 URL 路徑中不存在文件或目錄時,Firebase 託管才會應用重寫規則。當請求觸發重寫規則時,瀏覽器返回指定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": {
"functionId": "bigben",
"region": "us-central1" // optional (see note below)
"pinTag": true // optional (see note below)
}
} ]
}
如果
hosting.rewrites
配置的function
塊中省略了region
,Firebase CLI 會嘗試從函數的源代碼中自動檢測區域,如果未指定,則默認為us-central1
。如果函數的源代碼不可用,CLI 會嘗試從已部署的函數中檢測區域。如果該函數位於多個區域,則 CLI 要求在hosting.rewrites
配置中指定region
。
pinTag
功能僅在 Cloud Functions for Firebase(第二代)中可用。通過此功能,您可以確保用於生成站點動態內容的每個功能與您的靜態託管資源和託管配置保持同步。此外,此功能還允許您在託管預覽頻道上預覽對函數的重寫。如果您將
"pinTag": true
添加到hosting.rewrites
配置的function
塊中,那麼“固定”功能將與您的靜態託管資源和配置一起部署,即使在運行時也是如此。如果您回滾網站的某個版本,“固定”功能也會回滾。
firebase deploy --only hosting 此功能依賴於Cloud Run 標籤,每個服務的標籤限制為 1000 個,每個區域的標籤限制為 2000 個。這意味著經過數百次部署後,站點的最舊版本可能會停止工作。
添加此重寫規則並部署到 Firebase(使用firebase deploy
)後,可以通過以下 URL 訪問您的函數:
您的 Firebase 子域:
PROJECT_ID .web.app/bigben
和PROJECT_ID .firebaseapp.com/bigben
任何連接的自定義域:
CUSTOM_DOMAIN /bigben
當使用 Hosting 將請求重定向到函數時,支持的 HTTP 請求方法包括GET
、 POST
、 HEAD
、 PUT
、 DELETE
、 PATCH
和OPTIONS
。不支持REPORT
或PROFIND
等其他方法。
將請求直接發送到 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)
}
} ]
}
借助此功能,您可以確保用於生成網站動態內容的 Cloud Run 服務修訂版與靜態託管資源和託管配置保持同步。此外,此功能還允許您預覽對 Cloud Run on Hosting 預覽通道的重寫。
如果您將
"pingTag": true
添加到hosting.rewrites
配置的run
塊中,則您的靜態託管資源和配置將在部署時固定到 Cloud Run 服務的最新版本。如果您回滾網站的某個版本,“固定”Cloud Run 服務的修訂版本也會回滾。此功能依賴於Cloud Run 標籤,每個服務的標籤限制為 1000 個,每個區域的標籤限制為 2000 個。這意味著經過數百次部署後,站點的最舊版本可能會停止工作。
添加此重寫規則並部署到 Firebase(使用firebase deploy
)後,可以通過以下 URL 訪問您的容器映像:
您的 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 服務與託管並置:
-
us-west1
-
us-central1
-
us-east1
-
europe-west1
-
asia-east1
以下區域支持從託管重寫到 Cloud Run:
-
asia-east1
-
asia-east2
-
asia-northeast1
-
asia-northeast2
-
asia-northeast3
-
asia-south1
-
asia-south2
-
asia-southeast1
-
asia-southeast2
-
australia-southeast1
-
australia-southeast2
-
europe-central2
-
europe-north1
-
europe-southwest1
-
europe-west1
-
europe-west12
-
europe-west2
-
europe-west3
-
europe-west4
-
europe-west6
-
europe-west8
-
europe-west9
-
me-central1
-
me-west1
-
northamerica-northeast1
-
northamerica-northeast2
-
southamerica-east1
-
southamerica-west1
-
us-central1
-
us-east1
-
us-east4
-
us-east5
-
us-south1
-
us-west1
-
us-west2
-
us-west3
-
us-west4
-
us-west1
-
us-central1
-
us-east1
-
europe-west1
-
asia-east1
創建自定義域動態鏈接
您可以使用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 | 必須設置為
| |
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": "*"
} ]
} ]
}
"hosting": { // ... // Add the "headers" attribute within "hosting" "headers": [ { // Applies 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" } ] }, { // A regular expression-based rewrite equivalent to the above behavior "regex": ".+/\w+\.(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
屬性包含一組定義,其中每個定義必須包含下表中的字段。
場地 | 描述 | ||
---|---|---|---|
headers | |||
source (推薦)或正則 regex | URL 模式,如果與初始請求 URL 匹配,則觸發 Hosting 應用自定義標頭 要創建與自定義 404 頁面匹配的標頭,請使用 | ||
(子) headers 數組 | 託管應用於請求路徑的自定義標頭 每個子標頭必須包含一個 | ||
key | 標頭的名稱,例如Cache-Control | ||
value | 標頭的值,例如max-age=7200 |
您可以在描述提供動態內容和託管微服務的託管部分了解有關Cache-Control
的更多信息。您還可以了解有關CORS標頭的更多信息。
控制.html
擴展名
選修的cleanUrls
屬性允許您控制 URL 是否應包含.html
擴展名。
當true
時,託管會自動從上傳的文件 URL 中刪除.html
擴展名。如果請求中添加了.html
擴展名,託管會執行301
重定向到同一路徑,但會消除.html
擴展名。
以下是如何通過包含cleanUrls
屬性來控制 URL 中包含.html
的情況:
"hosting": {
// ...
// Drops `.html` from uploaded URLs
"cleanUrls": true
}
控制尾部斜杠
選修的trailingSlash
屬性允許您控制靜態內容 URL 是否應包含尾部斜杠。
- 當
true
時,託管會重定向 URL 以添加尾部斜杠。 - 當
false
時,託管會重定向 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",
}
}