Định cấu hình hành vi Lưu trữ

Với Firebase Hosting, bạn có thể định cấu hình hành vi lưu trữ tuỳ chỉnh cho các yêu cầu đến trang web của mình.

Bạn có thể định cấu hình những gì cho Hosting?

  • Chỉ định những tệp trong thư mục dự án cục bộ mà bạn muốn triển khai đến Firebase Hosting. Tìm hiểu cách thực hiện.

  • Phân phát trang 404/Không tìm thấy tuỳ chỉnh. Tìm hiểu cách thực hiện.

  • Thiết lập redirects cho những trang mà bạn đã di chuyển hoặc xoá. Tìm hiểu cách thực hiện.

  • Thiết lập rewrites cho bất kỳ mục đích nào sau đây:

  • Thêm headers để truyền thông tin bổ sung về một yêu cầu hoặc phản hồi, chẳng hạn như cách trình duyệt nên xử lý trang và nội dung của trang (xác thực, lưu vào bộ nhớ đệm, mã hoá, v.v.). Tìm hiểu cách thực hiện.

  • Thiết lập các quy tắc viết lại quốc tế hoá (i18n) để phân phát nội dung cụ thể dựa trên lựa chọn ưu tiên về ngôn ngữ và/hoặc quốc gia của người dùng. Tìm hiểu cách thực hiện (trang khác).

Bạn xác định cấu hình Hosting ở đâu?

Bạn xác định cấu hình Firebase Hosting trong tệp firebase.json. Firebase sẽ tự động tạo tệp firebase.json ở gốc thư mục dự án khi bạn chạy lệnh firebase init.

Bạn có thể xem ví dụ về cấu hình firebase.json đầy đủ (chỉ bao gồm Firebase Hosting) ở cuối trang này. Xin lưu ý rằng tệp firebase.json cũng có thể chứa cấu hình cho các dịch vụ khác của Firebase.

Bạn có thể kiểm tra nội dung firebase.json đã triển khai bằng cách sử dụng Hosting REST API.

Thứ tự ưu tiên của các phản hồi Hosting

Đôi khi, các lựa chọn cấu hình Firebase Hosting khác nhau được mô tả trên trang này có thể trùng lặp. Nếu có xung đột, Hosting sẽ xác định phản hồi của mình theo thứ tự ưu tiên sau:

  1. Không gian tên dành riêng bắt đầu bằng một phân đoạn đường dẫn /__/*
  2. Đã định cấu hình lệnh chuyển hướng
  3. Nội dung tĩnh khớp chính xác
  4. Đã định cấu hình viết lại
  5. Trang 404 tuỳ chỉnh
  6. Trang 404 mặc định

Nếu bạn đang sử dụng viết lại i18n, phạm vi của thứ tự ưu tiên xử lý 404 và so khớp chính xác sẽ được mở rộng để phù hợp với "nội dung i18n" của bạn.

Chỉ định những tệp cần triển khai

Các thuộc tính mặc định – publicignore – có trong tệp firebase.json mặc định sẽ xác định những tệp trong thư mục dự án của bạn cần được triển khai cho dự án Firebase.

Cấu hình hosting mặc định trong tệp firebase.json có dạng như sau:

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

công khai

Bắt buộc
Thuộc tính public chỉ định thư mục để triển khai Firebase Hosting. Giá trị mặc định là một thư mục có tên public, nhưng bạn có thể chỉ định đường dẫn của bất kỳ thư mục nào, miễn là thư mục đó tồn tại trong thư mục dự án của bạn.

Sau đây là tên được chỉ định mặc định của thư mục cần triển khai:

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

  // ...
}

Bạn có thể thay đổi giá trị mặc định thành thư mục mà bạn muốn triển khai:

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

  // ...
}

bỏ qua

Không bắt buộc
Thuộc tính ignore chỉ định các tệp cần bỏ qua khi triển khai. Nó có thể lấy glob theo cách mà Git xử lý .gitignore.

Sau đây là các giá trị mặc định cho những tệp cần bỏ qua:

"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
  ]
}

Tuỳ chỉnh trang 404/Không tìm thấy

Không bắt buộc
Bạn có thể phân phát một lỗi 404 Not Found tuỳ chỉnh khi người dùng cố gắng truy cập vào một trang không tồn tại.

Tạo một tệp mới trong thư mục public của dự án, đặt tên là 404.html, sau đó thêm nội dung 404 Not Found tuỳ chỉnh vào tệp.

Firebase Hosting sẽ hiển thị nội dung của trang 404.html tuỳ chỉnh này nếu trình duyệt kích hoạt lỗi 404 Not Found trên miền hoặc miền con của bạn.

Định cấu hình lệnh chuyển hướng

Không bắt buộc
Sử dụng lệnh chuyển hướng URL để ngăn các đường liên kết bị hỏng nếu bạn đã di chuyển một trang hoặc để rút ngắn URL. Ví dụ: bạn có thể chuyển hướng trình duyệt từ example.com/team sang example.com/about.html.

Chỉ định lệnh chuyển hướng URL bằng cách tạo một thuộc tính redirects chứa một mảng các đối tượng (gọi là "quy tắc chuyển hướng"). Trong mỗi quy tắc, hãy chỉ định một mẫu URL. Nếu mẫu này khớp với đường dẫn URL của yêu cầu, thì Hosting sẽ phản hồi bằng một lệnh chuyển hướng đến URL đích được chỉ định.

Sau đây là cấu trúc cơ bản cho một thuộc tính redirects. Ví dụ này chuyển hướng các yêu cầu đến /foo bằng cách đưa ra một yêu cầu mới đến /bar.

"hosting": {
  // ...

  // Returns a permanent redirect to "/bar" for requests to "/foo" (but not "/foo/**")
  "redirects": [ {
    "source": "/foo",
    "destination": "/bar",
    "type": 301
  } ]
}

Thuộc tính redirects chứa một mảng các quy tắc chuyển hướng, trong đó mỗi quy tắc phải bao gồm các trường trong bảng bên dưới.

Firebase Hosting so sánh giá trị source hoặc regex với tất cả đường dẫn URL ở đầu mỗi yêu cầu (trước khi trình duyệt xác định xem có tệp hoặc thư mục nào tồn tại ở đường dẫn đó hay không). Nếu tìm thấy kết quả trùng khớp, thì máy chủ gốc Firebase Hosting sẽ gửi một phản hồi chuyển hướng HTTPS, yêu cầu trình duyệt đưa ra một yêu cầu mới tại URL destination.

Trường Mô tả
redirects
source (nên dùng)
hoặc regex

Một mẫu URL. Nếu khớp với URL yêu cầu ban đầu, mẫu này sẽ kích hoạt Hosting để áp dụng lệnh chuyển hướng

destination

Một URL tĩnh mà trình duyệt sẽ thực hiện một yêu cầu mới

URL này có thể là đường dẫn tương đối hoặc đường dẫn tuyệt đối.

type

Mã phản hồi HTTPS

  • Sử dụng loại 301 cho "Chuyển vĩnh viễn"
  • Sử dụng loại 302 cho "Đã tìm thấy" (Chuyển hướng tạm thời)

Ghi lại các phân đoạn URL để chuyển hướng

Không bắt buộc
Đôi khi, bạn có thể cần nắm bắt các phân đoạn cụ thể của mẫu URL trong quy tắc chuyển hướng (giá trị source hoặc regex), sau đó sử dụng lại các phân đoạn này trong đường dẫn destination của quy tắc.

Định cấu hình quy tắc viết lại

Không bắt buộc
Sử dụng một quy tắc viết lại để hiển thị cùng một nội dung cho nhiều URL. Quy tắc viết lại đặc biệt hữu ích khi so khớp mẫu, vì bạn có thể chấp nhận mọi URL khớp với mẫu và cho phép mã phía máy khách quyết định nội dung cần hiển thị.

Bạn cũng có thể sử dụng các quy tắc viết lại để hỗ trợ những ứng dụng sử dụng HTML5 pushState cho hoạt động điều hướng. Khi một trình duyệt cố gắng mở một đường dẫn URL khớp với mẫu URL source hoặc regex đã chỉ định, trình duyệt sẽ nhận được nội dung của tệp tại URL destination thay thế.

Chỉ định việc viết lại URL bằng cách tạo một thuộc tính rewrites chứa một mảng các đối tượng (gọi là "quy tắc viết lại"). Trong mỗi quy tắc, hãy chỉ định một mẫu URL. Nếu mẫu này khớp với đường dẫn URL của yêu cầu, thì Hosting sẽ phản hồi như thể dịch vụ được cung cấp URL đích đã chỉ định.

Sau đây là cấu trúc cơ bản cho một thuộc tính rewrites. Ví dụ này phân phát index.html cho các yêu cầu đối với những tệp hoặc thư mục không tồn tại.

"hosting": {
  // ...

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

Thuộc tính rewrites chứa một mảng các quy tắc viết lại, trong đó mỗi quy tắc phải bao gồm các trường trong bảng bên dưới.

Firebase Hosting chỉ áp dụng quy tắc viết lại nếu không có tệp hoặc thư mục nào tại một đường dẫn URL khớp với mẫu URL source hoặc regex đã chỉ định. Khi một yêu cầu kích hoạt quy tắc viết lại, trình duyệt sẽ trả về nội dung thực tế của tệp destination được chỉ định thay vì lệnh chuyển hướng HTTP.

Trường Mô tả
rewrites
source (nên dùng)
hoặc regex

Một mẫu URL. Nếu khớp với URL yêu cầu ban đầu, mẫu này sẽ kích hoạt Hosting để áp dụng việc viết lại

destination

Một tệp cục bộ phải tồn tại

URL này có thể là đường dẫn tương đối hoặc đường dẫn tuyệt đối.

Yêu cầu trực tiếp đến một hàm

Bạn có thể dùng rewrites để phân phát một hàm từ URL Firebase Hosting. Ví dụ sau đây là một đoạn trích từ phân phát nội dung động bằng Cloud Functions.

Ví dụ: để chuyển tất cả các yêu cầu từ trang /bigben trên trang web Hosting của bạn để thực thi hàm 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)
    }
  } ]
}

Sau khi thêm quy tắc viết lại này và triển khai cho Firebase (bằng cách sử dụng firebase deploy), bạn có thể truy cập vào hàm của mình thông qua các URL sau:

  • Các miền phụ Firebase của bạn:
    PROJECT_ID.web.app/bigbenPROJECT_ID.firebaseapp.com/bigben

  • Mọi miền tuỳ chỉnh được kết nối:
    CUSTOM_DOMAIN/bigben

Khi chuyển hướng các yêu cầu đến các hàm bằng Hosting, các phương thức yêu cầu HTTP được hỗ trợ là GET, POST, HEAD, PUT, DELETE, PATCHOPTIONS. Các phương thức khác như REPORT hoặc PROFIND không được hỗ trợ.

Yêu cầu trực tiếp đến một vùng chứa Cloud Run

Bạn có thể dùng rewrites để truy cập vào một vùng chứa Cloud Run từ URL Firebase Hosting. Ví dụ sau đây là một đoạn trích từ phân phát nội dung động bằng Cloud Run.

Ví dụ: để chuyển tất cả các yêu cầu từ trang /helloworld trên trang web Hosting của bạn nhằm kích hoạt quá trình khởi động và chạy một phiên bản vùng chứa 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)
   }
 } ]
}

Sau khi thêm quy tắc viết lại này và triển khai vào Firebase (bằng firebase deploy), bạn có thể truy cập vào hình ảnh vùng chứa thông qua các URL sau:

  • Các miền phụ Firebase của bạn:
    PROJECT_ID.web.app/helloworldPROJECT_ID.firebaseapp.com/helloworld

  • Mọi miền tuỳ chỉnh được kết nối:
    CUSTOM_DOMAIN/helloworld

Khi chuyển hướng các yêu cầu đến vùng chứa Cloud Run bằng Hosting, các phương thức yêu cầu HTTP được hỗ trợ là GET, POST, HEAD, PUT, DELETE, PATCHOPTIONS. Các phương thức khác như REPORT hoặc PROFIND không được hỗ trợ.

Để có hiệu suất tốt nhất, hãy đặt dịch vụ Cloud Run cùng với Hosting bằng cách sử dụng các khu vực sau:

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

Chúng tôi hỗ trợ việc viết lại thành Cloud Run từ Hosting ở các khu vực sau:

  • 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

Bạn có thể sử dụng rewrites để tạo miền tuỳ chỉnh Dynamic Links. Hãy truy cập vào tài liệu Dynamic Links để biết thông tin chi tiết về cách thiết lập miền tuỳ chỉnh cho Dynamic Links.

  • Chỉ sử dụng miền tuỳ chỉnh của bạn cho 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
      } ]
    }
  • Chỉ định tiền tố đường dẫn miền tuỳ chỉnh để sử dụng cho 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
      } ]
    }

Để định cấu hình Dynamic Links trong tệp firebase.json, bạn cần phải có những thông tin sau:

Trường Mô tả
appAssociation

Phải được đặt thành AUTO

  • Nếu bạn không thêm thuộc tính này vào cấu hình, thì giá trị mặc định cho appAssociationAUTO.
  • Bằng cách đặt thuộc tính này thành AUTO, Hosting có thể tự động tạo các tệp assetlinks.jsonapple-app-site-association khi chúng được yêu cầu.
rewrites
source

Đường đi mà bạn muốn dùng cho Dynamic Links

Không giống như các quy tắc viết lại đường dẫn thành URL, quy tắc viết lại cho Dynamic Links không được chứa biểu thức chính quy.

dynamicLinks Phải được đặt thành true

Định cấu hình tiêu đề

Không bắt buộc
Tiêu đề cho phép máy khách và máy chủ truyền thông tin bổ sung cùng với yêu cầu hoặc phản hồi. Một số nhóm tiêu đề có thể ảnh hưởng đến cách trình duyệt xử lý trang và nội dung của trang, bao gồm cả quyền kiểm soát truy cập, xác thực, lưu vào bộ nhớ đệm và mã hoá.

Chỉ định tiêu đề phản hồi tuỳ chỉnh, dành riêng cho tệp bằng cách tạo một thuộc tính headers chứa một mảng các đối tượng tiêu đề. Trong mỗi đối tượng, hãy chỉ định một mẫu URL. Nếu mẫu này khớp với đường dẫn URL của yêu cầu, thì Hosting sẽ áp dụng các tiêu đề phản hồi tuỳ chỉnh đã chỉ định.

Sau đây là cấu trúc cơ bản cho một thuộc tính headers. Ví dụ này áp dụng tiêu đề CORS cho tất cả các tệp phông chữ.

"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": "*"
    } ]
  } ]
}

Thuộc tính headers chứa một mảng các định nghĩa, trong đó mỗi định nghĩa phải bao gồm các trường trong bảng bên dưới.

Trường Mô tả
headers
source (nên dùng)
hoặc regex

Một mẫu URL. Nếu mẫu này khớp với URL yêu cầu ban đầu, thì Hosting sẽ kích hoạt để áp dụng tiêu đề tuỳ chỉnh

Để tạo một tiêu đề khớp với trang 404 tuỳ chỉnh, hãy sử dụng 404.html làm giá trị source hoặc regex.

mảng (phụ) headers

Tiêu đề tuỳ chỉnh mà Hosting áp dụng cho đường dẫn yêu cầu

Mỗi tiêu đề phụ phải có một cặp keyvalue (xem hai hàng tiếp theo).

key Tên của tiêu đề, ví dụ: Cache-Control
value Giá trị cho tiêu đề, ví dụ: max-age=7200

Bạn có thể tìm hiểu thêm về Cache-Control trong phần Hosting mô tả việc phân phát nội dung động và lưu trữ các vi dịch vụ. Bạn cũng có thể tìm hiểu thêm về phần đầu CORS.

Kiểm soát tiện ích .html

Không bắt buộc
Thuộc tính cleanUrls cho phép bạn kiểm soát việc URL có nên bao gồm tiện ích .html hay không.

Khi true, Hosting tự động xoá đuôi .html khỏi URL của tệp đã tải lên. Nếu đuôi .html được thêm vào yêu cầu, Hosting sẽ thực hiện lệnh chuyển hướng 301 đến cùng một đường dẫn nhưng loại bỏ đuôi .html.

Sau đây là cách kiểm soát việc thêm .html vào URL bằng cách thêm thuộc tính cleanUrls:

"hosting": {
  // ...

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

Kiểm soát dấu gạch chéo

Không bắt buộc
Thuộc tính trailingSlash cho phép bạn kiểm soát việc URL nội dung tĩnh có nên chứa dấu gạch chéo ở cuối hay không.

  • Khi true, Hosting chuyển hướng URL để thêm dấu gạch chéo ở cuối.
  • Khi false, Hosting chuyển hướng URL để xoá dấu gạch chéo ở cuối.
  • Khi không được chỉ định, Hosting chỉ sử dụng dấu gạch chéo ở cuối cho các tệp chỉ mục thư mục (ví dụ: about/index.html).

Sau đây là cách kiểm soát dấu gạch chéo ở cuối bằng cách thêm thuộc tính trailingSlash:

"hosting": {
  // ...

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

Thuộc tính trailingSlash không ảnh hưởng đến việc viết lại nội dung động do Cloud Functions hoặc Cloud Run phân phát.

So khớp mẫu glob

Các lựa chọn cấu hình Firebase Hosting sử dụng rộng rãi ký hiệu khớp mẫu glob với extglob, tương tự như cách Git xử lý các quy tắc gitignoreBower xử lý các quy tắc ignore. Trang wiki này là một tài liệu tham khảo chi tiết hơn, nhưng sau đây là nội dung giải thích về các ví dụ được dùng trên trang này:

  • firebase.json – Chỉ khớp với tệp firebase.json trong thư mục gốc của thư mục public

  • ** – Khớp với mọi tệp hoặc thư mục trong một thư mục con bất kỳ

  • * – Chỉ khớp với các tệp và thư mục trong thư mục gốc của public

  • **/.* – Khớp với mọi tệp bắt đầu bằng . (thường là tệp ẩn, chẳng hạn như trong thư mục .git) trong một thư mục con tuỳ ý

  • **/node_modules/** – Khớp với mọi tệp hoặc thư mục trong một thư mục con tuỳ ý của thư mục node_modules. Thư mục này có thể nằm trong một thư mục con tuỳ ý của thư mục public

  • **/*.@(jpg|jpeg|gif|png) – So khớp mọi tệp trong một thư mục con bất kỳ kết thúc bằng chính xác một trong các tệp sau: .jpg, .jpeg, .gif hoặc .png

Ví dụ về cấu hình Hosting đầy đủ

Sau đây là ví dụ về cấu hình firebase.json đầy đủ cho Firebase Hosting. Xin lưu ý rằng tệp firebase.json cũng có thể chứa cấu hình cho các dịch vụ khác của 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",

  }
}