設定託管行為

使用 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 會依下列優先順序決定回應:

  1. /__/* 路徑區隔開頭的保留命名空間
  2. 已設定的重新導向
  3. 完全相符的靜態內容
  4. 已設定重新編寫
  5. 自訂 404 網頁
  6. 預設 404 網頁

如果您使用 i18n 重寫,系統會擴大完全相符和 404 處理優先順序的範圍,以配合您的「i18n 內容」。

指定要部署的檔案

預設屬性 (publicignore) 包含在預設 firebase.json 檔案中,用於定義專案目錄中應部署至 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 相同的方式,使用 glob

以下是檔案的預設忽略值:

"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 錯誤,系統就會顯示這個自訂 404.html 頁面的內容。Firebase Hosting

設定重新導向

選用
如果您已遷移網頁或要縮短網址,請使用網址重新導向功能,避免連結失效。舉例來說,您可以將瀏覽器從 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 屬性包含重新導向規則的陣列,每項規則都必須包含下表中的欄位。

Firebase Hosting 會在每個要求的開頭,將 sourceregex 值與所有網址路徑進行比較 (瀏覽器判斷該路徑中是否有檔案或資料夾之前)。如果找到相符項目,Firebase Hosting原始伺服器會傳送 HTTPS 重新導向回應,告知瀏覽器在 destination 網址發出新要求。

欄位 說明
redirects
source (建議)
regex

如果與初始要求網址相符,就會觸發 Hosting 套用重新導向的網址模式

destination

瀏覽器應提出新要求的靜態網址

這個網址可以是相對或絕對路徑。

type

HTTPS 回應代碼

  • 針對「永久移動」使用 301 類型
  • 使用「Found」(暫時重新導向) 的 302 類型

擷取網址區隔以供重新導向

選用
有時您可能需要擷取重新導向規則網址模式 (sourceregex 值) 的特定區段,然後在規則的 destination 路徑中重複使用這些區段。

設定重寫

選用
使用重寫功能,針對多個網址顯示相同內容。重寫功能特別適合用於模式比對,因為您可以接受符合模式的任何網址,並讓用戶端程式碼決定要顯示的內容。

您也可以使用重新編寫功能,支援使用 HTML5 pushState 進行導覽的應用程式。當瀏覽器嘗試開啟符合指定 sourceregex 網址模式的網址路徑時,瀏覽器會改為取得 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 屬性包含重新編寫規則的陣列,每項規則都必須包含下表中的欄位。

只有在與指定的 sourceregex 網址模式相符的網址路徑中,沒有檔案或目錄時,Firebase Hosting 才會套用重寫規則。要求觸發重寫規則時,瀏覽器會傳回指定 destination 檔案的實際內容,而不是 HTTP 重新導向。

欄位 說明
rewrites
source (建議)
regex

如果與初始要求網址相符,就會觸發 Hosting 套用重寫的網址模式

destination

必須存在的本機檔案

這個網址可以是相對或絕對路徑。

直接要求函式

您可以使用 rewritesFirebase 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)
    }
  } ]
}

新增這項重寫規則並部署至 Firebase (使用 firebase deploy) 後,您就能透過下列網址存取函式:

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

  • 任何已連結的自訂網域
    CUSTOM_DOMAIN/bigben

使用 Hosting 將要求重新導向至函式時,支援的 HTTP 要求方法包括 GETPOSTHEADPUTDELETEPATCHOPTIONS。不支援 REPORTPROFIND 等其他方法。

直接要求 Cloud Run 容器

您可以使用 rewritesFirebase Hosting 網址存取 Cloud Run 容器。以下範例是使用 Cloud Run 放送動態內容的節錄內容。

舉例來說,如要將網站上 /helloworld 網頁的所有要求導向至 helloworld 容器執行個體,以觸發啟動及執行作業,請使用下列程式碼:Hosting

"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) 後,即可透過下列網址存取容器映像檔:

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

  • 任何已連結的自訂網域
    CUSTOM_DOMAIN/helloworld

將要求重新導向至 Cloud Run 容器時,支援的 HTTP 要求方法為 GETPOSTHEADPUTDELETEPATCHOPTIONSHosting不支援 REPORTPROFIND 等其他方法。

如要獲得最佳效能,請使用下列區域,將 Cloud Run 服務與 Hosting 放在同一位置:

  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1

下列地區支援從 Hosting 重新編寫為 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 建立自訂網域 Dynamic Links。如要進一步瞭解如何為 Dynamic Links 設定自訂網域,請參閱Dynamic Links說明文件。

  • Dynamic Links使用自訂網域

    "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
      } ]
    }
  • 指定要用於 Dynamic Links 的自訂網域路徑前置字元

    "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 檔案中設定 Dynamic Links,請完成下列步驟:

欄位 說明
appAssociation

必須設為「AUTO

  • 如果未在設定中加入這項屬性,appAssociation 的預設值為 AUTO
  • 將這項屬性設為 AUTO 後,Hosting 就能在要求時動態產生 assetlinks.jsonapple-app-site-association 檔案。
rewrites
source

您要用於「Dynamic Links」的路徑

與將路徑重新編寫為網址的規則不同,Dynamic Links 的重新編寫規則不得包含規則運算式。

dynamicLinks 必須設為「true

設定標頭

選用
標頭可讓用戶端和伺服器在傳送要求或回應時,一併傳遞額外資訊。部分標頭組合可能會影響瀏覽器處理網頁及其內容的方式,包括存取控制、驗證、快取和編碼。

建立包含標頭物件陣列的 headers 屬性,即可指定檔案專屬的自訂回應標頭。在每個物件中,指定網址模式。如果要求網址路徑與該模式相符,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

如果與初始要求網址相符,就會觸發 Hosting 套用自訂標頭的網址模式

如要建立與自訂 404 網頁相符的標頭,請使用 404.html 做為 sourceregex 值。

(子) headers 陣列

Hosting 套用至要求路徑的自訂標頭

每個子標題都必須包含 keyvalue 配對 (請參閱接下來的兩列)。

key 標頭名稱,例如 Cache-Control
value 標題的值,例如 max-age=7200

如要進一步瞭解 Cache-Control,請參閱Hosting一節,瞭解如何提供動態內容及代管微服務。您也可以進一步瞭解 CORS 標頭。

控制 .html 擴充功能

選用
cleanUrls 屬性可讓您控管網址是否應包含 .html 擴充功能。

true 會自動從上傳的檔案網址中捨棄 .html 擴充功能。如果在要求中加入 .html 擴充功能,Hosting 會執行 301 重新導向至相同路徑,但會排除 .html 擴充功能。Hosting

如要控管網址中是否加入 .html,請加入 cleanUrls 屬性:

"hosting": {
  // ...

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

控制尾端斜線

選用
trailingSlash 屬性可讓您控管靜態內容網址是否應包含尾端斜線。

  • true 會重新導向網址,並加入尾端斜線 Hosting
  • false 時,Hosting 會重新導向網址,移除結尾斜線。
  • 如未指定,Hosting 只會對目錄索引檔案使用尾端斜線 (例如 about/index.html)。

如要新增 trailingSlash 屬性來控管尾部斜線,請按照下列步驟操作:

"hosting": {
  // ...

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

trailingSlash 屬性不會影響 Cloud FunctionsCloud Run 提供的動態內容重寫。

Glob 模式比對

Firebase Hosting 設定選項大量使用 glob 模式比對標記,類似於 Git 處理 gitignore 規則和 Bower 處理 ignore 規則的方式。這個維基頁面是更詳細的參考資料,但以下說明本頁使用的範例:

  • firebase.json:只比對 public 目錄根目錄中的 firebase.json 檔案

  • **:比對任意子目錄中的任何檔案或資料夾

  • *:只比對 public 目錄根層級的檔案和資料夾

  • **/.*:比對任意子目錄中以 . 開頭的任何檔案 (通常是隱藏檔案,例如 .git 資料夾中的檔案)

  • **/node_modules/**:比對 node_modules 資料夾任意子目錄中的任何檔案或資料夾,而 node_modules 資料夾本身可以位於 public 目錄的任意子目錄中

  • **/*.@(jpg|jpeg|gif|png):比對任意子目錄中結尾為下列其中一個字元的檔案:.jpg.jpeg.gif.png

完整 Hosting 設定範例

以下是 Firebase Hosting 的完整 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",

  }
}