Azure App Service虚拟应用Angular刷新404 如何配置Azure管道路由规则
先澄清一个认知偏差
staticwebapp.config.json 是 Azure Static Web Apps 这个独立服务的专属配置文件,你当前使用的是普通Azure App Service(基于IIS托管层),默认不会读取这个文件的规则,就算通过Pipeline把这个文件传上去也不会生效,不用在这个文件上浪费时间。
你遇到的刷新报错本质是:Angular这类单页应用的路由是浏览器端实现的,刷新时请求打到App Service,IIS找不到和URL路径对应的物理文件就直接返回404,只要给IIS配置对应重写规则,找不到文件的时候回退到对应应用的index.html交给前端路由处理即可,这个逻辑和你用什么CI/CD工具、代码托管在哪没有关系。
具体实现步骤
1. 准备SPA路由回退配置
普通App Service用IIS标准的web.config实现重写,效果和Static Web Apps的NavigationFallback完全一致。你需要给两个Angular虚拟应用各准备一份如下内容的web.config文件:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="SPA Route Fallback" stopProcessing="true"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> </conditions> <action type="Rewrite" url="./index.html" /> </rule> </rules> </rewrite> <staticContent> <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" /> </staticContent> </system.webServer> </configuration>
注意:这份配置放在独立虚拟应用的目录下时,作用域仅限当前虚拟应用,重写规则只会回退到当前Angular应用的
index.html,不会影响根路径/下托管的Blazor应用,不用担心里程碑冲突。根路径的Blazor应用保持现有配置即可,不需要加这个文件。
2. 集成到Azure Pipeline自动部署
你不需要迁移代码仓库,直接在现有Azure DevOps Pipeline里加少量配置就能把规则随应用一起发布,两种方式可选:
- 方式一:配置跟随代码仓库管理(推荐)
把web.config文件分别放到两个Angular项目的src目录下,修改Angular项目根目录的angular.json,在对应项目的build.options.assets数组里加入src/web.config,这样每次执行ng build的时候,构建工具会自动把配置文件复制到发布产物的根目录,后续Pipeline执行构建、发布任务时,会自动把配置文件传到App Service对应的虚拟应用物理路径下,不需要额外修改Pipeline逻辑。 - 方式二:Pipeline侧注入配置(不侵入业务代码)
如果你不想改动Angular项目的代码,可以把两份web.config上传到Azure Pipeline的安全文件库,或者存到仓库的通用配置目录,在Build管道里执行完ng build步骤之后,加两个「复制文件」任务,分别把对应配置文件复制到两个Angular构建产物的根目录,再走后续的发布流程即可。
3. 发布后验证
正常执行完Pipeline发布之后,直接访问Angular应用的子路由刷新,就不会再出现资源找不到的404错误。如果第一次部署没生效,去App Service的Kudu控制台确认下两个虚拟应用的物理路径下确实存在web.config,以及App Service已经开启了URL Rewrite模块(该模块默认是开启的,不需要手动调整)。
内容的提问来源于stack exchange,提问作者OneClutteredMind

