Angular应用部署至App Service后assets文件夹访问返回404错误
问题描述
我的assets文件夹在构建产物中已正确打包,但部署到App Service后,浏览器访问相关资源时返回404错误。
以下是angular.json中配置构建时包含该文件夹所有内容的相关代码:
"assets": [ "src/assets" ]
App Service上该文件夹内的实际文件情况:
Chrome控制台中出现的报错:
报错由尝试加载json文件的翻译服务触发,相关代码如下:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; import { HttpClientModule, HttpClient } from '@angular/common/http'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http, '/assets/translations/', '.json'); } @NgModule({ declarations: [], imports: [ CommonModule, HttpClientModule, TranslateModule.forRoot({ defaultLanguage: 'en', loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient], }, }), ], exports: [TranslateModule], }) export class NgxTranslateModule { }
该功能在本地运行时完全正常。查到的所有解决方案都提到配置web.config即可修复该问题,但当前项目为.NET Core技术栈,该配置文件不会生效。
解决方案
这个问题的核心原因是**.NET Core的静态文件中间件默认没有正确映射部署后的assets路径,或者没有开启对.json类型文件的访问支持**,按照以下步骤排查修复即可:
- 首先确认静态文件中间件的注册顺序和配置
打开.NET Core项目的Startup.cs(.NET 6+为Program.cs),确保UseStaticFiles()中间件在路由、权限中间件之前注册,并且显式指定Angular构建产物的静态文件目录。
如果是用Angular CLI和.NET Core分开构建、把Angular产物放到wwwroot下的模式,配置参考:// .NET 6+ Program.cs 示例 var app = builder.Build(); // 注意顺序:静态文件配置必须放在授权、路由配置之前 app.UseStaticFiles(); // 默认映射wwwroot下的静态资源,这行不能遗漏 // 如果Angular产物不在wwwroot路径,需要显式指定目录: // app.UseStaticFiles(new StaticFileOptions // { // FileProvider = new PhysicalFileProvider( // Path.Combine(builder.Environment.ContentRootPath, "AngularApp/dist")), // RequestPath = "" // }); app.UseRouting(); app.UseAuthorization(); // 后面接接口路由、SPA兜底路由配置 app.MapControllers(); app.MapFallbackToFile("index.html"); // SPA路由兜底必须放在所有配置最后 - 补充.json文件的MIME类型映射
.NET Core静态文件中间件默认已经支持.json对应application/json的MIME类型,但如果环境内有自定义配置覆盖了默认规则,需要显式添加映射,在静态文件配置中补充:var provider = new FileExtensionContentTypeProvider(); // 显式注册json文件类型 provider.Mappings[".json"] = "application/json"; app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = provider }); - 检查部署路径是否匹配
代码中TranslateHttpLoader写死了绝对路径/assets/translations/,如果App Service上应用不是部署在站点根目录,而是挂在子应用路径下,这个绝对路径会指向错误位置。本地运行正常是因为本地Angular dev server默认跑在根路径。
修复方式是改为基于Angular应用部署基路径自动拼接路径,引入APP_BASE_HREF处理:import { APP_BASE_HREF } from '@angular/common'; // 工厂方法注入baseHref export function HttpLoaderFactory(http: HttpClient, @Inject(APP_BASE_HREF) baseHref: string) { return new TranslateHttpLoader(http, `${baseHref}assets/translations/`, '.json'); } @NgModule({ declarations: [], imports: [ CommonModule, HttpClientModule, TranslateModule.forRoot({ defaultLanguage: 'en', loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient, APP_BASE_HREF], // 新增依赖项 }, }), ], exports: [TranslateModule], }) - 验证部署文件权限与完整性
登录App Service的Kudu控制台,进入site/wwwroot/assets/translations路径,确认翻译json文件确实存在,且应用运行身份对该目录有读取权限,排除部署时文件漏传、权限不足导致的404。
补充说明:.NET Core项目并非完全不支持
web.config,部署到Azure App Service(底层为IIS托管)时,项目根目录或wwwroot下的web.config中IIS相关配置是可以生效的,只是.NET Core的请求处理逻辑不再依赖web.config的模块配置。如果以上配置修改后仍有问题,可以补充web.config的静态资源规则,不会和.NET Core本身的配置冲突。
内容的提问来源于stack exchange,提问作者Francis Ducharme
相关产品推荐
相关产品推荐

