設定 Azure Static Web Apps

您可以在 staticwebapp.config.json 檔案中 定義 Azure Static Web Apps 的組態,以控制下列設定:

注意

先前用來設定路由的 routes.json 已被取代。 如本文所述,請使用 staticwebapp.config.json 來設定靜態 Web 應用程式的路由和其他設定。

本檔是關於 Azure Static Web Apps,這是獨立的產品,與Azure 儲存體的靜態網站裝載 功能分開

檔案位置

staticwebapp.config.json 的建議位置 位於工作流程檔案 設定為 app_location 的資料夾。 不過,檔案可以放在資料夾內的任何子資料夾中,做為 app_location 。 此外,如果有建置步驟,您必須確定建置步驟會將檔案輸出至output_location的根目錄。

如需詳細資訊, 請參閱範例組態 檔。

重要

如果 staticwebapp.config.json 存在,則會忽略已被取代的 routes.json 檔案

路由

您可以在靜態 Web 應用程式中定義一或多個路由的規則。 路由規則可讓您限制特定角色的使用者存取,或執行重新導向或重寫等動作。 路由定義為路由規則的陣列。 如需使用範例, 請參閱範例組態檔

  • 規則會在陣列中 routes 定義,即使您只有一個路由也一樣。
  • 規則會依照陣列中 routes 出現的順序進行評估。
  • 規則評估會在第一個比對時停止。 當 屬性和陣列中的值符合要求時 route ,就會發生比對 methods 。 每個要求最多可以符合一個規則。

路由考慮與驗證(識別使用者)和授權(將能力指派給使用者)概念明顯重迭。 請務必閱讀 本文的驗證和授權 指南。

定義路由

每個規則都是由路由模式所組成,以及一或多個選擇性規則屬性。 路由規則定義于陣列中 routes 。 如需使用範例, 請參閱範例組態檔

重要

route只有 和 methods (如果指定) 屬性可用來判斷規則是否符合要求。

Rule 屬性 必要 預設值 Comment
route Yes n/a 呼叫端要求的路由模式。
methods No 所有方法 定義符合路由的要求方法陣列。 可用的方法包括: GET 、、 HEADPOSTPUTDELETE 、、 CONNECTOPTIONSTRACEPATCH
rewrite No n/a 定義從要求傳回的檔案或路徑。
  • 與規則互斥 redirect
  • 重寫規則不會變更瀏覽器的位置。
  • 值必須相對於應用程式的根目錄。
redirect No n/a 定義要求的檔案或路徑重新導向目的地。
  • 與規則互斥 rewrite
  • 重新導向規則會變更瀏覽器的位置。
  • 預設回應碼是 ( 302 暫時重新導向),但您可以使用 (永久重新導向) 覆寫 301
statusCode No 301302 用於重新導向 回應的 HTTP 狀態碼
headers No n/a 新增至回應的 HTTP 標頭 集。
  • 當路由特定標頭與全域標頭在回應中相同時,路由特定標頭會覆寫 globalHeaders
  • 若要移除標頭,請將值設定為空字串。
allowedRoles No 匿名 定義存取路由所需的角色名稱陣列。
  • 有效的字元包括 a-zA-Z0-9_
  • 內建角色 anonymous 會套用至所有使用者。
  • 內建角色 authenticated 會套用至任何登入的使用者。
  • 使用者必須至少屬於一個角色。
  • 角色會以 OR 為基礎進行比對。
    • 如果使用者位於任何列出的角色中,則會授與存取權。
  • 個別使用者透過 邀請 與角色相關聯。

每個屬性在要求/回應管線中都有特定用途。

目的 屬性
比對路由 route, methods
比對規則並授權之後的程式 rewrite (修改要求)

redirect、 、 headersstatusCode (修改回應)
比對路由之後授權 allowedRoles

指定路由模式

屬性 route 可以是確切的路由或萬用字元模式。

確切路由

若要定義確切的路由,請將檔案的完整路徑放在 屬性中 route

{
  "route": "/profile/index.html",
  "allowedRoles": ["authenticated"]
}

此規則會比對 /profile/index.html 檔案 的要求。 因為 index.html 是預設檔案,因此規則也會符合資料夾 ( /profile /profile/ ) 的要求。

重要

如果您在 屬性中使用 route 資料夾路徑 ( /profile/profile/ ) ,則它不符合 /profile/index.html 檔案 的要求。 保護提供檔案的路由時,請一律使用檔案的完整路徑,例如 /profile/index.html

萬用字元模式

萬用字元規則會比對路由模式中的所有要求,只有在路徑結尾才支援,而且可由副檔名篩選。 如需使用範例, 請參閱範例組態檔

例如,若要實作行事曆應用程式的路由,您可以重寫屬於 行事曆 路由下的所有 URL,以提供單一檔案。

{
  "route": "/calendar*",
  "rewrite": "/calendar.html"
}

calendar.html 檔案接著可以使用用戶端路由,為 、 和 /calendar/overview/calendar/january/1/calendar/2020 URL 變化提供不同的檢視。

注意

/calendar/* 路由模式會比對 /calendar/ 路徑下 的所有要求。 不過,它不符合 /calendar /calendar.html 路徑 的要求。 使用 /calendar* 來比對以 /calendar 開頭 的所有要求。

您可以依副檔名篩選萬用字元相符專案。 例如,如果您想要新增只符合指定路徑中 HTML 檔案的規則,您可以建立下列規則:

{
  "route": "/articles/*.html",
  "headers": {
    "Cache-Control": "public, max-age=604800, immutable"
  }
}

若要篩選多個副檔名,您會在大括弧中包含選項,如下列範例所示:

{
  "route": "/images/thumbnails/*.{png,jpg,gif}",
  "headers": {
    "Cache-Control": "public, max-age=604800, immutable"
  }
}

萬用字元路由的常見使用案例包括:

  • 為整個路徑模式提供特定檔案
  • 強制執行驗證和授權規則
  • 實作特製化快取規則

使用角色保護路由

路由會藉由將一或多個角色名稱新增至規則的 allowedRoles 陣列來保護。 如需使用範例, 請參閱範例組態檔

重要

路由規則只能保護從靜態 Web Apps 提供之路由的 HTTP 要求。 許多前端架構會使用用戶端路由,修改瀏覽器中的路由,而不向靜態 Web Apps 發出要求。 路由規則不會保護用戶端路由。 用戶端應該呼叫 HTTP API 來擷取敏感性資料。 在傳回資料之前,請確定 API 會先驗證 使用者的身分 識別。

根據預設,每個使用者都屬於內建的 anonymous 角色,而所有登入的使用者都是 authenticated 角色的成員。 或者,使用者會透過 邀請 與自訂角色相關聯。

例如,若要將路由限制為僅限已驗證的使用者,請將內 authenticated 建角色新增至 allowedRoles 陣列。

{
  "route": "/profile*",
  "allowedRoles": ["authenticated"]
}

您可以視需要在陣列中 allowedRoles 建立新的角色。 若要將路由限制為僅限系統管理員,您可以在陣列中 allowedRoles 定義名為 administrator 的自己的角色。

{
  "route": "/admin*",
  "allowedRoles": ["administrator"]
}
  • 您可以完全控制角色名稱;您的角色不一定要遵守任何清單。
  • 個別使用者透過 邀請 與角色相關聯。

重要

保護內容時,請盡可能指定確切的檔案。 如果您有許多要保護的檔案,請在共用前置詞之後使用萬用字元。 例如:保護以 /profile 開頭的所有可能路由,包括 /profile /profile*

限制對整個應用程式的存取

應用程式中的每個路由都需要驗證很常見。 若要啟用此功能,請新增符合所有路由的規則,並在陣列中包含 allowedRolesauthenticated 建角色。

下列範例組態會封鎖匿名存取,並將所有未經驗證的使用者重新導向至 Microsoft Entra 登入頁面。

{
  "routes": [
    {
      "route": "/*",
      "allowedRoles": ["authenticated"]
    }
  ],
  "responseOverrides": {
    "401": {
      "statusCode": 302,
      "redirect": "/.auth/login/aad"
    }
  }
}

注意

根據預設,會啟用所有預先設定的識別提供者。 若要封鎖驗證提供者,請參閱 驗證和授權

後援路由

單頁應用程式通常依賴用戶端路由。 這些用戶端路由規則會更新瀏覽器的視窗位置,而不要求回到伺服器。 如果您重新整理頁面,或直接移至用戶端路由規則所產生的 URL,則需要伺服器端後援路由來提供適當的 HTML 頁面,這通常是用戶端應用程式的 index.html

您可以藉由新增 navigationFallback 區段來定義後援規則。 下列範例會針對不符合已部署檔案的所有靜態檔案要求,傳回 /index.html

{
  "navigationFallback": {
    "rewrite": "/index.html"
  }
}

您可以藉由定義篩選,來控制哪些要求會傳回後援檔案。 在下列範例中 ,會排除 /images 資料夾中特定路由的要求,以及 /css 資料夾中的所有檔案 ,而不要傳回後援檔案。

{
  "navigationFallback": {
    "rewrite": "/index.html",
    "exclude": ["/images/*.{png,jpg,gif}", "/css/*"]
  }
}

例如,使用下面的目錄結構,上述導覽後援規則會導致下表詳述的結果。

├── images
│   ├── logo.png
│   ├── headshot.jpg
│   └── screenshot.gif
│
├── css
│   └── global.css
│
└── index.html
要求... 返回。。。 具有狀態...
/about/ /index.html 檔案 200
/images/logo.png 影像檔案 200
/images/icon.svg /index.html 檔案 - 因為 svg 副檔名未列在篩選中 /images/*.{png,jpg,gif} 200
/images/unknown.png 找不到檔案錯誤 404
/css/unknown.css 找不到檔案錯誤 404
/css/global.css 樣式表單檔案 200
/images /css 資料夾以外的 任何其他檔案 /index.html 檔案 200

重要

如果您要從已被取代的 routes.json 檔案移轉 ,請勿在 路由規則 中包含舊版後援路由 ( "route": "/*" )。

全域標頭

globalHeaders 段會提供一組套用至每個回應的 HTTP 標頭,除非由 路由標頭 規則覆寫,否則會傳回路由和全域標頭的標頭聯集。

如需使用範例, 請參閱範例組態檔

若要移除標頭,請將值設定為空字串 ( "" )。

全域標頭的一些常見使用案例包括:

  • 自訂快取規則
  • 強制執行安全性原則
  • 編碼設定
  • 設定跨原始來源資源分享 ( CORS

下列範例會實作自訂 CORS 組態。

{
  "globalHeaders": {
    "Access-Control-Allow-Origin": "https://example.com",
    "Access-Control-Allow-Methods": "POST, GET, OPTIONS"
  }
}

注意

全域標頭不會影響 API 回應。 API 回應中的標頭會保留並傳回給用戶端。

回應覆寫

responseOverrides 區段可讓您定義伺服器傳回錯誤碼時的自訂回應。 如需使用範例, 請參閱範例組態檔

下列 HTTP 代碼可供覆寫:

狀態碼 意義 可能的原因
400 錯誤要求 不正確邀請連結
401 未經授權 未驗證時對受限制頁面的要求
403 禁止
  • 使用者已登入,但沒有檢視頁面所需的角色。
  • 使用者已登入,但執行時間無法從其身分識別宣告取得使用者詳細資料。
  • 使用自訂角色登入網站的使用者太多,因此執行時間無法登入使用者。
404 找不到 找不到檔案

下列範例組態示範如何覆寫錯誤碼。

{
  "responseOverrides": {
    "400": {
      "rewrite": "/invalid-invitation-error.html"
    },
    "401": {
      "statusCode": 302,
      "redirect": "/login"
    },
    "403": {
      "rewrite": "/custom-forbidden-page.html"
    },
    "404": {
      "rewrite": "/custom-404.html"
    }
  }
}

平台

platform 段會控制平臺特定設定,例如 API 語言執行平臺版本。

選取 API 語言執行平臺版本

若要設定 API 語言執行平臺版本,請將 區段中的 屬性 platform 設定 apiRuntime 為下列其中一個支援的值。

語言執行時間版本 作業系統 Azure Functions 版本 apiRuntime 終止支援日期
.NET Core 3.1 Windows 3.x dotnet:3.1 2022 年 12 月 3 日
.NET 6.0 進程 Windows 4.x dotnet:6.0 -
.NET 6.0 隔離 Windows 4.x dotnet-isolated:6.0 -
.NET 7.0 隔離 Windows 4.x dotnet-isolated:7.0 -
.NET 8.0 隔離 Windows 4.x dotnet-isolated:8.0 -
Node.js 12.x Linux 3.x node:12 2022 年 12 月 3 日
Node.js 14.x Linux 4.x node:14 -
Node.js 16.x Linux 4.x node:16 -
Node.js 18.x
(公開預覽)
Linux 4.x node:18 -
Python 3.8 Linux 4.x python:3.8 -
Python 3.9 Linux 4.x python:3.9 -
Python 3.10 Linux 4.x python:3.10 -

.NET

若要變更 .NET 應用程式中的執行時間版本,請變更 TargetFramework csproj 檔案中的 值。 雖然是選擇性的,但如果您在 staticwebapp.config.json 檔案中 設定值 apiRuntime ,請確定該值符合您在 csproj 檔案中 定義的值。

下列範例示範如何將 NET 8.0 的 元素更新 TargetFramework 為 csproj 檔案中的 API 語言執行平臺版本。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    ...
  </PropertyGroup>
...

Node.js

下列範例組態示範如何使用 apiRuntime 屬性,在 staticwebapp.config.json 檔案中 選取 Node.js 16 作為 API 語言執行平臺版本。

{
  ...
  "platform": {
    "apiRuntime": "node:16"
  }
  ...
}

Python

下列範例組態示範如何使用 apiRuntime 屬性,在 staticwebapp.config.json 檔案中 選取 Python 3.8 作為 API 語言執行平臺版本。

{
  ...
  "platform": {
    "apiRuntime": "python:3.8"
  }
  ...
}

網路

networking 段會控制靜態 Web 應用程式的網路設定。 若要限制對應用程式的存取,請在 中 allowedIpRanges 指定允許的 IP 位址區塊清單。 如需允許 IP 位址區塊數目的詳細資訊,請參閱 Azure 靜態 Web Apps 中的配額。

注意

網路設定僅適用于 Azure Static Web Apps Standard 方案。

在無類別網域間路由 (CIDR) 標記法中定義每個 IPv4 位址區塊。 若要深入瞭解 CIDR 標記法,請參閱 無類別網域間路由 。 每個 IPv4 位址區塊都可以表示公用或私人位址空間。 如果您只想要允許從單一 IP 位址存取,您可以使用 /32 CIDR 區塊。

{
  "networking": {
    "allowedIpRanges": [
      "10.0.0.0/24",
      "100.0.0.0/32",
      "192.168.100.0/22"
    ]
  }
}

指定一或多個 IP 位址區塊時,來自不符合 值 allowedIpRanges 之 IP 位址的要求會遭到拒絕存取。

除了 IP 位址區塊之外,您也可以在陣列中 allowedIpRanges 指定 服務標籤 ,以限制特定 Azure 服務的流量。

"networking": {
  "allowedIpRanges": ["AzureFrontDoor.Backend"]
}

驗證

如需如何限制路由給已驗證使用者的詳細資訊,請參閱 使用角色 保護路由。

停用已驗證路徑的快取

如果您設定 手動與 Azure Front Door 整合,您可能想要停用安全路由的快取。 啟用 企業級邊緣 後,此設定已為您設定。

若要停用安全路由的 Azure Front Door 快取,請將 新增 "Cache-Control": "no-store" 至路由標頭定義。

例如:

{
    "route": "/members",
    "allowedRoles": ["authenticated, members"],
    "headers": {
        "Cache-Control": "no-store"
    }
}

轉送閘道

本節 forwardingGateway 會設定如何從 CDN 或 Azure Front Door 等轉送閘道存取靜態 Web 應用程式。

注意

轉送閘道組態僅適用于 Azure Static Web Apps Standard 方案。

允許轉送的主機

清單 allowedForwardedHosts 會指定要在 X-Forwarded-Host 標頭中 接受的主機名稱。 如果清單中的相符網域,Static Web Apps 會在建構重新導向 URL 時使用 X-Forwarded-Host 值,例如成功登入之後。

若要讓靜態 Web Apps 在轉送閘道後正確運作,來自閘道的要求必須在標頭中包含 X-Forwarded-Host 正確的主機名稱,且相同的主機名稱必須列在 中 allowedForwardedHosts

"forwardingGateway": {
  "allowedForwardedHosts": [
    "example.org",
    "www.example.org",
    "staging.example.org"
  ]
}

X-Forwarded-Host如果標頭不符合清單中的值,要求仍會成功,但標頭不會用於回應中。

必要標頭

必要的標頭是 HTTP 標頭,每個要求都必須傳送至您的網站。 必要標頭的其中一個用法是拒絕存取網站,除非每個要求中都存在所有必要的標頭。

例如,下列組態示範如何新增 Azure Front Door 的唯一識別碼 ,以限制從特定 Azure Front Door 實例存取您的網站。 如需完整詳細資料, 請參閱設定 Azure Front Door 教學 課程。

"forwardingGateway": {
  "requiredHeaders": {
    "X-Azure-FDID" : "692a448c-2b5d-4e4d-9fcc-2bc4a6e2335f"
  }
}
  • 索引鍵/值組可以是任一字元串集
  • 索引鍵不區分大小寫
  • 值區分大小寫

尾端斜線

結尾斜線是 / URL 結尾的 。 傳統上,尾端斜線 URL 是指網頁伺服器上的目錄,而非尾端斜線則表示檔案。

無論搜尋引擎是檔案還是目錄,搜尋引擎都會分別處理這兩個 URL。 當這兩個 URL 都轉譯相同的內容時,您的網站會提供重複的內容,這會對搜尋引擎優化產生負面影響。 明確設定時,靜態 Web Apps 會套用一組 URL 正規化和重新導向規則,以協助改善網站的效能和 SEO。

下列正規化和重新導向規則適用于每個可用的組態:

永遠

當您將 設定 trailingSlashalways 時,所有不包含尾端斜線的要求都會重新導向至尾端斜線 URL。 例如, /contact 會重新導向至 /contact/

"trailingSlash": "always"
要求... 返回。。。 具有狀態... 和路徑...
/about /about/index.html 檔案 301 /about/
/about/ /about/index.html 檔案 200 /about/
/about/index.html /about/index.html 檔案 301 /about/
/聯繫 /contact.html 檔案 301 /聯繫/
/聯繫/ /contact.html 檔案 200 /聯繫/
/contact.html /contact.html 檔案 301 /聯繫/

永不

當設定 trailingSlashnever 時,結尾斜線結尾的所有要求都會重新導向至非尾端斜線 URL。 例如, /contact/ 會重新導向至 /contact

"trailingSlash": "never"
要求... 返回。。。 具有狀態... 和路徑...
/about /about/index.html 檔案 200 /about
/about/ /about/index.html 檔案 301 /about
/about/index.html /about/index.html 檔案 301 /about
/聯繫 /contact.html 檔案 200 /聯繫
/聯繫/ /contact.html 檔案 301 /聯繫
/contact.html /contact.html 檔案 301 /聯繫

自動

當您設定為 trailingSlashauto 時,所有對資料夾的要求都會重新導向至具有尾端斜線的 URL。 所有對檔案的要求都會重新導向至非尾端斜線 URL。

"trailingSlash": "auto"
要求... 返回。。。 具有狀態... 和路徑...
/about /about/index.html 檔案 301 /about/
/about/ /about/index.html 檔案 200 /about/
/about/index.html /about/index.html 檔案 301 /about/
/聯繫 /contact.html 檔案 200 /聯繫
/聯繫/ /contact.html 檔案 301 /聯繫
/contact.html /contact.html 檔案 301 /聯繫

為獲得最佳網站效能,請使用下列其中 alwaysnever 一種 或 auto 模式設定尾端斜線策略。

根據預設,當省略組 trailingSlash 態時,Static Web Apps 會套用下列規則:

要求... 返回。。。 具有狀態... 和路徑...
/about /about/index.html 檔案 200 /about
/about/ /about/index.html 檔案 200 /about/
/about/index.html /about/index.html 檔案 200 /about/index.html
/聯繫 /contact.html 檔案 200 /聯繫
/聯繫/ /contact.html 檔案 301 /聯繫
/contact.html /contact.html 檔案 200 /contact.html

範例設定檔

{
  "trailingSlash": "auto",
  "routes": [
    {
      "route": "/profile*",
      "allowedRoles": ["authenticated"]
    },
    {
      "route": "/admin/index.html",
      "allowedRoles": ["administrator"]
    },
    {
      "route": "/images/*",
      "headers": {
        "cache-control": "must-revalidate, max-age=15770000"
      }
    },
    {
      "route": "/api/*",
      "methods": ["GET"],
      "allowedRoles": ["registeredusers"]
    },
    {
      "route": "/api/*",
      "methods": ["PUT", "POST", "PATCH", "DELETE"],
      "allowedRoles": ["administrator"]
    },
    {
      "route": "/api/*",
      "allowedRoles": ["authenticated"]
    },
    {
      "route": "/customers/contoso*",
      "allowedRoles": ["administrator", "customers_contoso"]
    },
    {
      "route": "/login",
      "rewrite": "/.auth/login/github"
    },
    {
      "route": "/.auth/login/twitter",
      "statusCode": 404
    },
    {
      "route": "/logout",
      "redirect": "/.auth/logout"
    },
    {
      "route": "/calendar*",
      "rewrite": "/calendar.html"
    },
    {
      "route": "/specials",
      "redirect": "/deals",
      "statusCode": 301
    }
  ],
  "navigationFallback": {
    "rewrite": "index.html",
    "exclude": ["/images/*.{png,jpg,gif}", "/css/*"]
  },
  "responseOverrides": {
    "400": {
      "rewrite": "/invalid-invitation-error.html"
    },
    "401": {
      "redirect": "/login",
      "statusCode": 302
    },
    "403": {
      "rewrite": "/custom-forbidden-page.html"
    },
    "404": {
      "rewrite": "/404.html"
    }
  },
  "globalHeaders": {
    "content-security-policy": "default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'"
  },
  "mimeTypes": {
    ".json": "text/json"
  }
}

根據上述組態,檢閱下列案例。

要求... 結果...
/配置 檔 已驗證的使用者會提供 /profile/index.html 檔案。 未經驗證的使用者會由 401 回應覆寫規則重新導向至 /login
/admin /admin/ /admin/index.html 系統管理員角色中的 已驗證使用者會提供 /admin/index.html 檔案。 未在系統管理員角色中 驗證的使用者會提供 403 錯誤 1 未經驗證的使用者會重新導向至 /login
/images/logo.png 使用自訂快取規則提供映射,其中最大存留期為 182 天(15,770,000 秒)。
/api/admin GET來自已註冊使用者 角色中 已驗證使用者的要求會傳送至 API。 未在已註冊使用者 角色和未經驗證的使用者中 ,已驗證的使用者會提供 401 錯誤。

POSTPUTPATCHDELETE 來自系統管理員 角色中 已驗證使用者的要求會傳送至 API。 未在系統管理員 角色和未經驗證的使用者中 ,已驗證的使用者會提供 401 錯誤。
/customers/contoso 屬於系統管理員或customers_contoso角色的 已驗證使用者會提供 /customers/contoso/index.html 檔案。 未在系統管理員或customers_contoso角色中 驗證的使用者會提供 403 錯誤 1 未經驗證的使用者會重新導向至 /login
/登錄 未經驗證的使用者會面臨向 GitHub 進行驗證的挑戰。
/.auth/login/twitter 路由規則停用 Twitter 授權時, 404 會傳回錯誤,其會回復為狀態 200 代碼為 /index.html 提供服務
/登出 使用者會登出任何驗證提供者。
/calendar/2021/01 瀏覽器會提供 /calendar.html 檔案。
/特價 瀏覽器會永久重新導向至 /deals
/data.json MIME text/json 類型所提供的檔案。
/about ,或任何符合用戶端路由模式的資料夾 /index.html 檔案會提供 200 狀態碼。
/images/ 資料夾中不存在的 檔案 錯誤 404

1 您可以使用回應覆寫規則 來提供自訂錯誤頁面

限制

staticwebapp.config.json 檔案存在 下列限制。

  • 檔案大小上限為 20 KB
  • 最多 50 個不同的角色

如需一般限制和限制,請參閱配額一文

下一步