設定 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 、、、POST PUT HEAD DELETE 、、、OPTIONS CONNECT 、 TRACE 和 。 PATCH |
rewrite |
No | n/a | 定義從要求傳回的檔案或路徑。
|
redirect |
No | n/a | 定義要求的檔案或路徑重新導向目的地。 |
statusCode |
No | 301 或 302 用於重新導向 |
回應的 HTTP 狀態代碼。 |
headers |
No | n/a | 新增至回應的 HTTP 標頭 集。
|
allowedRoles |
No | anonymous | 定義存取路由所需的角色名稱陣列。
|
每個屬性在要求/回應管線中都有特定用途。
目的 | 屬性 |
---|---|
比對路由 | route , methods |
比對規則並授權之後的程式 | rewrite (修改要求)redirect 、 、 headers statusCode (修改回應) |
比對路由之後授權 | 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*
限制對整個應用程式的存取
您通常想要要求驗證應用程式中的每個路由。 若要鎖定您的路由,請新增符合所有路由的規則,並在陣列中包含allowedRoles
內authenticated
建角色。
下列範例組態會封鎖匿名存取,並將所有未經驗證的使用者重新導向至 Microsoft Entra 登入頁面。
{
"routes": [
{
"route": "/*",
"allowedRoles": ["authenticated"]
}
],
"responseOverrides": {
"401": {
"statusCode": 302,
"redirect": "/.auth/login/aad"
}
}
}
注意
根據預設,會啟用所有預先設定的識別提供者。 若要封鎖驗證提供者,請參閱 驗證和授權。
後援路由
單頁應用程式通常依賴用戶端路由。 這些用戶端路由規則會更新瀏覽器的視窗位置,而不要求回到伺服器。 如果您重新整理頁面,或直接移至用戶端路由規則所產生的 URL,則需要伺服器端後援路由來提供適當的 HTML 頁面。 後援頁面通常指定為 用戶端應用程式的 index.html。
注意
路由規則不會套用至觸發 navigationFallback
的要求。
您可以藉由新增 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
│
├── about.html
└── index.html
要求... | 返回。。。 | 具有狀態... |
---|---|---|
/大約/ | /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 |
/about.html | HTML 頁面。 | 200 |
/images 或 /css 資料夾以外的任何其他路徑,不符合已部署檔案的路徑。 | /index.html 檔案。 | 200 |
全域標頭
區 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 |
- |
Node.js 20.x (預覽) | Linux | 4.x | node:20 |
- |
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
屬性,將 Node.js 16 選取為 staticwebapp.config.json 檔案中的 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
會設定如何從轉送網關存取靜態 Web 應用程式,例如 內容傳遞網路 (CDN) 或 Azure Front Door。
注意
轉送閘道組態僅適用於 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 效能。
下列正規化和重新導向規則適用於每個可用的組態:
永遠
當您將 設定 trailingSlash
為 always
時,所有不包含尾端斜線的要求都會重新導向至尾端斜線 URL。 例如, /contact
會重新導向至 /contact/
。
"trailingSlash": "always"
要求... | 返回。。。 | 具有狀態... | 和路徑... |
---|---|---|---|
/大約 | /about/index.html 檔案 | 301 |
/大約/ |
/大約/ | /about/index.html 檔案 | 200 |
/大約/ |
/about/index.html | /about/index.html 檔案 | 301 |
/大約/ |
/privacy.html | /privacy.html 檔案 | 301 |
/隱私/ |
永不
當設定 trailingSlash
為 never
時,結尾斜線結尾的所有要求都會重新導向至非有軌斜線 URL。 例如, /contact/
會重新導向至 /contact
。
"trailingSlash": "never"
要求... | 返回。。。 | 具有狀態... | 和路徑... |
---|---|---|---|
/大約 | /about/index.html 檔案 | 200 |
/大約 |
/大約/ | /about/index.html 檔案 | 301 |
/大約 |
/about/index.html | /about/index.html 檔案 | 301 |
/大約 |
/privacy.html | /privacy.html 檔案 | 301 |
/隱私 |
自動
當您設定為 trailingSlash
auto
時,所有對資料夾的要求都會重新導向至具有尾端斜線的URL。 所有對檔案的要求都會重新導向至非有軌斜線 URL。
"trailingSlash": "auto"
要求... | 返回。。。 | 具有狀態... | 和路徑... |
---|---|---|---|
/大約 | /about/index.html 檔案 | 301 |
/大約/ |
/大約/ | /about/index.html 檔案 | 200 |
/大約/ |
/about/index.html | /about/index.html 檔案 | 301 |
/大約/ |
/privacy.html | /privacy.html 檔案 | 301 |
/隱私 |
若要獲得最佳網站效能,請使用下列其中 always
一種、 never
或 auto
模式來設定尾端斜線策略。
根據預設,當省略組 trailingSlash
態時,Static Web Apps 會套用下列規則:
要求... | 返回。。。 | 具有狀態... | 和路徑... |
---|---|---|---|
/大約 | /about/index.html 檔案 | 200 |
/大約 |
/大約/ | /about/index.html 檔案 | 200 |
/大約/ |
/about/index.html | /about/index.html 檔案 | 200 |
/about/index.html |
/privacy.html | /privacy.html 檔案 | 200 |
/privacy.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/x",
"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 錯誤。POST 、PUT 、 PATCH 和 DELETE 來自系統管理員角色中已驗證使用者的要求會傳送至 API。 未在系統管理員角色和未經驗證的使用者中,已驗證的使用者會提供401 錯誤。 |
/customers/contoso | 屬於系統管理員或customers_contoso角色的已驗證使用者會提供 /customers/contoso/index.html 檔案。 沒有在系統管理員或customers_contoso角色中驗證的使用者會提供403 錯誤1。 未經驗證的用戶會重新導向至 /login。 |
/登錄 | 未經驗證的用戶會面臨向 GitHub 進行驗證的挑戰。 |
_/.auth/login/x | 由於路由規則會停用 X 授權, 404 因此會傳回錯誤。 此錯誤接著會回復為 /index.html提供200 狀態代碼。 |
/註銷 | 用戶會註銷任何驗證提供者。 |
/calendar/2021/01 | 瀏覽器會提供 /calendar.html 檔案。 |
/特價 | 瀏覽器會永久重新導向至 /deals。 |
/data.json | MIME text/json 類型所提供的檔案。 |
/about,或任何符合用戶端路由模式的資料夾 | /index.html 檔案會以200 狀態代碼提供。 |
/images/ 資料夾中不存在的檔案 | 錯誤 404 。 |
1 您可以使用回應覆寫規則來提供自訂錯誤頁面。
Restrictions
staticwebapp.config.json檔案有下列限制。
- 檔案大小上限為 20 KB
- 最多50個不同的角色