Azure托管Angular应用静态资源加载失败报Unexpected token '<'错误
问题根因
你遇到的问题由三个核心配置错误共同导致:
- 中间件执行顺序错误,重写路径逻辑不严谨
- 构建参数与Angular配置冲突,静态资源无哈希后缀引发缓存问题
- 无判断的强制路径重写导致响应已发送后仍修改请求,触发服务端报错
修复步骤
1. 修正Startup.cs中间件配置
首先调整中间件顺序,UseStaticFiles必须放在路径重写逻辑之前,同时仅当请求返回404、且为前端路由请求时才重写路径到index.html,修复后的代码如下:
public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 先处理静态资源请求 app.UseStaticFiles(); // 仅对404的非静态资源请求做前端路由回退 app.Use(async (context, next) => { await next(); // 只处理响应状态码为404、且不是API/带后缀的静态资源类的请求 if (context.Response.StatusCode == 404 && !context.Request.Path.StartsWithSegments("/api") && !Path.HasExtension(context.Request.Path.Value)) { context.Request.Path = "/index.html"; // 清空之前的响应内容避免报错 context.Response.Clear(); await next(); } }); } }
该修改同时解决了服务端StatusCode cannot be set报错,以及静态资源请求错误返回index.html的问题。
2. 修正构建命令参数
你package.json中的构建命令加了--output-hashing none,优先级高于angular.json中production配置的outputHashing: all,导致编译出的静态资源无哈希后缀,新版本部署后用户浏览器缓存的旧资源请求404触发回退逻辑。
修改package.json的build命令,删除--output-hashing none即可:
"build": "ng build --aot --prod"
后续构建出的js、css文件都会自带哈希后缀,部署新版本后不会出现旧缓存资源请求问题。
3. 可选优化:配置静态资源缓存规则
可以在UseStaticFiles中添加缓存配置,给带哈希后缀的静态资源设置长期缓存,给index.html设置不缓存,进一步避免缓存问题:
app.UseStaticFiles(new StaticFileOptions { OnPrepareResponse = ctx => { // index.html不缓存 if (ctx.File.Name.Equals("index.html", StringComparison.OrdinalIgnoreCase)) { ctx.Context.Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate"; ctx.Context.Response.Headers["Pragma"] = "no-cache"; ctx.Context.Response.Headers["Expires"] = "0"; } // 带哈希的静态资源缓存1年 else if (Regex.IsMatch(ctx.File.Name, @"\.[a-f0-9]{8}\.(js|css|png|jpg|svg)$")) { ctx.Context.Response.Headers["Cache-Control"] = "public, max-age=31536000, immutable"; } } });
内容的提问来源于stack exchange,提问作者Sharon Watinsan
相关产品推荐
相关产品推荐

