共用方式為


設定 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 陣列中定義路由規則。 如需使用量範例,請參閱範例組態檔

重要事項

只會使用 routemethods (如果指定) 屬性來判斷規則是否會比對要求。

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

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

目的 屬性
比對路由 routemethods
比對並授權規則之後的程序 rewrite (修改要求)

redirectheadersstatusCode (修改回應)
比對路由之後進行授權 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

萬用字元模式

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

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

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

然後,calendar.html 檔案可以使用用戶端路由,針對 URL 變化 (例如 /calendar/january/1/calendar/2020/calendar/overview) 提供不同的觀點。

附註

/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 陣列來保護路由。 如需使用量範例,請參閱範例組態檔

重要事項

路由規則只能保護從 Static Web Apps 所提供路由的 HTTP 要求。 許多前端架構都會使用用戶端路由,其可修改瀏覽器中的路由,而不會發出對 Static 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
要求... 會傳回... 狀態為...
/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
/about.html HTML 頁面。 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 窗戶 3.x dotnet:3.1 2022 年 12 月 3 日
.NET 6.0 同處理序 窗戶 4.x dotnet:6.0 2025年4月30日
.NET 8.0 同處理序 窗戶 4.x dotnet:8.0 -
.NET 6.0 隔離式 窗戶 4.x dotnet-isolated:6.0 2025年4月30日
.NET 7.0 隔離式 窗戶 4.x dotnet-isolated:7.0 2025年4月30日
.NET 8.0 隔離式 窗戶 4.x dotnet-isolated:8.0 -
.NET 9.0 隔離式 窗戶 4.x dotnet-isolated:9.0 -
Node.js 12.x Linux 3.x node:12 2022 年 12 月 3 日
Node.js 14.x Linux 4.x node:14 2025年4月30日
Node.js 16.x Linux 4.x node:16 2025年4月30日
Node.js 18.x Linux 4.x node:18 2025 年 5 月 31 日
Node.js 20.x Linux 4.x node:20 -
Python 3.8 Linux 4.x python:3.8 2025年4月30日
Python 3.9 Linux 4.x python:3.9 -
Python 3.10 Linux 4.x python:3.10 -
Python 3.11 Linux 4.x python:3.11 -

。NET

若要變更 .NET 應用程式中的執行階段版本,請變更 csproj 檔案中的 TargetFramework 值。 雖然為選擇性選項,但如果在 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 20 作為 staticwebapp.config.json 檔案中的 API 語言執行平臺版本。

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

Python(程式語言)

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

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

網路功能

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

附註

網路設定僅適用於 Azure Static Web Apps 標準方案。

在無類別網域間路由選擇 (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 標準方案。

允許轉送的主機

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

如需讓 Static 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 都轉譯相同的內容時,您的網站會提供重複的內容,這會對搜尋引擎最佳化 (SEO) 產生負面影響。 明確設定時,Azure Static Web Apps 會套用一組 URL 正規化和重新導向規則,以協助改善網站的效能和 SEO 效能。

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

一律

當您將 trailingSlash 設定為 always 時,所有不包含後置斜線的要求都會重新導向至後置斜線 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/
/privacy.html /privacy.html 檔案 301 /隱私/

永不

trailingSlash 設定為 never 時,後置斜線結尾的所有要求都會重新導向至非後置斜線 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
/privacy.html /privacy.html 檔案 301 /隱私

Auto

當您將 trailingSlash 設定為 auto 時,所有對資料夾的要求都會重新導向至具有後置斜線的 URL。 所有對檔案的要求都會重新導向至非後置斜線 URL。

"trailingSlash": "auto"
要求... 會傳回... 狀態為... 和路徑...
/about /about/index.html 檔案 301 /about/
/about/ /about/index.html 檔案 200 /about/
/about/index.html /about/index.html 檔案 301 /about/
/privacy.html /privacy.html 檔案 301 /隱私

若要獲得最佳網站效能,請使用 alwaysneverauto 其中一種模式來設定後置斜線策略。

根據預設,當省略 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
/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 已驗證的使用者會提供 /profile/index.html 檔案。 未驗證的使用者會依 401 回應覆寫規則重新導向至 /login
/admin/admin//admin/index.html administrators 角色中的已驗證使用者,會提供 /admin/index.html 檔案。 非 administrators 角色中的已驗證使用者,會提供 403 錯誤1。 未驗證的使用者會重新導向至 /login
/images/logo.png 使用自訂快取規則提供映像,其中存留期上限稍微超過 182 天 (15,770,000 秒)。
/api/admin 來自 registeredusers 角色中已驗證使用者的 GET 要求會傳送至 API。 非 administrators 角色中的已驗證使用者和未驗證使用者,會提供 401 錯誤。

來自 administrator 角色中已驗證使用者的 POSTPUTPATCHDELETE 要求會傳送至 API。 非 administrators 角色中的已驗證使用者和未驗證使用者,會提供 401 錯誤。
/customers/contoso 屬於 administratorcustomers_contoso 角色的已驗證使用者,會提供 /customers/contoso/index.html 檔案。 非 administratorcustomers_contoso 角色中的已驗證使用者,會提供 403 錯誤1。 未驗證的使用者會重新導向至 /login
/login 未經驗證的使用者會受到向 GitHub 驗證的查問。
_/.auth/login/x 由於路由規則會停用 X 授權,因此會傳回 404 錯誤。 此錯誤接著會回復為具有 200 狀態代碼的 /index.html
/logout 使用者已登出任何驗證提供者。
/calendar/2021/01 瀏覽器會提供 /calendar.html 檔案。
/specials 瀏覽器將永久重新導向至 /deals
/data.json 包含 text/json MIME 類型的檔案。
/about,或任何符合用戶端路由模式的資料夾 /index.html 檔案會包含 200 狀態碼。
/images/ 資料夾中不存在的檔案 404 錯誤。

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

限制

staticwebapp.config.json 檔案有下列限制。

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

如需一般限制事項的詳細資訊,請參閱配額一文。

後續步驟