你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
配置 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
(如果已指定)属性来确定规则是否与请求匹配。
规则属性 | 必选 | 默认值 | 注释 |
---|---|---|---|
route |
是 | 不适用 | 调用方请求的路由模式。
|
methods |
否 | 所有方法 | 定义与路由匹配的请求方法的数组。 可用方法包括:GET 、HEAD 、POST 、PUT 、DELETE 、CONNECT 、OPTIONS 、TRACE 和 PATCH 。 |
rewrite |
否 | 不适用 | 定义从请求返回的文件或路径。
|
redirect |
否 | 不适用 | 定义请求的文件或路径重定向目标。 |
statusCode |
否 | 用于重定向的 301 或 302 |
响应的 HTTP 状态代码。 |
headers |
否 | 不适用 | 添加到响应的一组 HTTP 头。
|
allowedRoles |
否 | 匿名 | 定义访问路由所需的角色名称数组。
|
每个属性在请求/响应管道中都有特定的用途。
目的 | 属性 |
---|---|
匹配路由 | 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
。
通配符模式
通配符规则匹配路由模式中的所有请求,仅支持在路径末尾使用。 有关用法示例,请参阅示例配置文件。
例如,若要为日历应用程序实现路由,可以重写 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
数组中来保护路由。 有关用法示例,请参阅示例配置文件。
重要
传递规则只能保护向静态 Web 应用中提供的路由发出的 HTTP 请求。 许多前端框架都使用在浏览器中修改路由(不向静态 Web 应用发出请求)的客户端路由。 传递规则不保护客户端路由。 客户端应调用 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 | 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 应用中的运行时版本,请更改 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
属性在 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 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"]
}
身份验证
默认身份验证提供程序,不需要配置文件中的设置。
自定义身份验证提供程序使用设置文件的
auth
部分。
若要详细了解如何将路由限制为经过身份验证的用户,请参阅使用角色保护路由。
为经过身份验证的路径禁用缓存
如果已设置了与 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 是指 Web 服务器上的目录,而非尾随斜杠 URL 则表示文件。
无论是文件还是目录,搜索引擎都会分开处理这两种 URL。 在这两种 URL 中呈现相同的内容时,你的网站会提供对搜索引擎优化 (SEO) 产生负面影响的重复内容。 显式配置后,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 |
/privacy/ |
从不
将 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 |
/privacy |
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 |
/privacy |
为了获得最佳网站性能,请使用 always
、never
或 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 |
/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 | 为充当 administrator 角色的经过身份验证的用户提供 /admin/index.html 文件。 为不充当 administrator 角色的经过身份验证的用户提供 403 错误 1。 未经身份验证的用户将重定向到 /login。 |
/images/logo.png | 使用自定义缓存规则提供图像,该规则中的最大期限略微超过 182天(15,770,000 秒)。 |
/api/admin | 将充当 registeredusers 角色的经过身份验证的用户发来的 GET 请求发送到 API。 为不充当 registeredusers 角色的经过身份验证的用户以及未经过身份验证的用户提供 401 错误。将充当 administrator 角色的经过身份验证的用户发来的 POST 、PUT 、PATCH 和 DELETE 请求发送到 API。 为不充当 administrator 角色的经过身份验证的用户以及未经过身份验证的用户提供 401 错误。 |
/customers/contoso | 为属于 administrator 或 customers_contoso 角色的经过身份验证的用户提供 /customers/contoso/index.html 文件 。 为不充当 administrator 或 customers_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 个不同角色
有关一般限制和局限性,请参阅有关配额的文章。