使用 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",
}
}