背景/目标
- 我有一个带有多个环境的应用程序,每个环境存储在CDN的子文件夹中。
- 例如:
cdn.com/dev
,cdn.com/test
- 例如:
- 我的目标是加载开发站点(
cdn.com/dev/index.html
)并从/dev/
路径加载相应的资源。
⚠️ℹ️ 我们正在使用一种“构建一次,多次部署”的策略,因此我无法在构建过程或类似过程中传递baseHref。
问题
到目前为止,无论我尝试什么,cdn.com/dev/index.html
都会尝试从根目录 (cdn.com/script.js
) 而不是子文件夹 (cdn.com/dev/script.js
) 加载脚本。
我尝试了什么
❌ 尝试1: 设置APP_BASE_HREF
并将其用作提供者
我在 index.html
中设置了一个 window 变量:
<script>
window['base-href'] = window.location.pathname;
console.log(window['base-href']);
</script>
接着我尝试使用该值通过提供者来传递给app.module.ts
中的APP_BASE_HREF
:
import { APP_BASE_HREF } from '@angular/common';
let baseHref = (window as { [key: string]: any })["base-href"] as string;
if (!baseHref.endsWith("/")) {
baseHref += "/";
}
// I only updated the providers array below
@NgModule({
declarations: [
AppComponent,
ComingSoonListComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule
],
providers: [
{
provide: APP_BASE_HREF,
useValue: baseHref
}
],
bootstrap: [AppComponent]
})
第一次尝试似乎没有起作用。
❌ 尝试二:稍微不太天真的尝试
我从index.html页面中删除了base
标签,以防它覆盖了其他东西。
在index.html中,我调用脚本来捕获路径名:
<script>
window['base-href'] = window.location.pathname;
console.log(window['base-href']);
</script>
</
在
app.module.ts
中,我创建了一个工厂方法来捕获窗口值并使用它:const baseHrefFactory = () => {
let baseHref = (window as { [key: string]: any })["base-href"] as string;
if (!baseHref.endsWith("/")) {
baseHref += "/";
}
console.log('TS: using baseHref of:', baseHref);
return baseHref;
}
// Note I just use the factory method below
@NgModule({
declarations: [
AppComponent,
ComingSoonListComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
],
providers: [{ provide: APP_BASE_HREF, useFactory: baseHrefFactory }],
bootstrap: [AppComponent],
})
export class AppModule { }
- 我可以看到窗口值已被设置(通过控制台日志记录)
- 似乎其他文件在我们能够以编程方式触发
APP_BASE_HREF
工厂之前尝试加载,并尝试从根路径而不是我设置的路径进行加载。 在本地运行时,它似乎运行良好,但可能仅因为路径自然为/
。
❌ 尝试3:直接在HTML中设置base
href
在<head>
标签中的index.html
文件中,在创建base
标签后:
<script>
var baseHref = window.location.pathname;
if (!baseHref.endsWith("/")) {
baseHref += "/";
}
console.log("setting a baseHref of:", baseHref);
document.getElementsByTagName("base")[0].href = baseHref;
</script>
- ✅ 我添加的 index.html 脚本正在运行(我看到了控制台日志)
- ✅ 适当的基础路径被选中(
/dev/
- 我在控制台日志中看到了它) - ✅ 基础标签被正确设置(我可以通过浏览器开发工具检查到这一点)
- ❌ 浏览器请求的URL不包含
/dev/
- 实际URL:
cdn.com/script.js
- 期望URL:
cdn.com/dev/script.js
- 实际URL:
❓(尚未尝试)我需要在部署时修改吗?
我是否需要在部署脚本中物理修改 index.html
,以使用正确的 <base>
标记中的 href
?那将是令人惊讶的,但我想这也是可能的。似乎这肯定是一个答案;只希望它不是唯一的答案。
问题
如何在运行时修改基础路径,以便 Angular 从正确的 URL 下载资源,包括 CDN 端点的子路径?我能否在运行时执行此操作,还是需要在部署时以编程方式设置?