window.location.origin 在 Angular 模块中为空

问题描述

我有一个应用程序和一个库,两个独立的存储库。我的应用使用我的库,我的库包含一个执行 http 请求的服务。

我的应用程序部署到多个环境中,我使用 Angular 的 environment.ts 文件来定义外部服务所在的位置。所有应用都通过网关提供服务,并位于同一个 window.location.origin。

ivy 已禁用,aot 已启用。

我的图书馆公开了一个 forRoot 如下:

  declarations: [
    ToggleDirective
  ],providers: [
    ToggleService,ToggleServiceConfig
  ],exports: [
    ToggleDirective
  ]
})
export class ToggleModule {
  static forRoot(config: ToggleServiceConfig): ModuleWithProviders<ToggleModule> {
    return {
      ngModule: ToggleModule,providers: [
        {provide: ToggleServiceConfig,useValue: config }
      ]
    };
  }
}

我的应用程序的 environment.ts 如下所示:

export const environment = {
   ...
   togglesUrl: window.location.origin + '/release-toggling',...
};

在我的应用的 app.module 中,我是这样配置的:


...

const releasetoggleServiceConfig: ToggleServiceConfig = {
    togglesUrl: environment.togglesUrl
};

...

@NgModule({
    declarations: [AppComponent],imports: [
        CoreModule,SharedModule,...
        ToggleModule.forRoot(releasetoggleServiceConfig)
    ],...
})
export class AppModule {}

如果我对 window.location.origin 进行硬编码(本地为 'localhost:4200'),那么它就可以正常工作。显然,这个窗口在这个阶段还不存在。这可能与 aot 有关,但不幸的是,这里不能禁用 aot。

这里正确传递 window.location.origin 的最佳模式/实践是什么。从技术上讲,在应用调用我的外部服务之前不需要它。

我对您的解决方案或建议感兴趣。这可能很容易解决,很多人以前都遇到过。

解决方法

所有应用都通过网关提供服务,并位于同一个 window.location.origin 上。

如果两个应用程序都位于同一个网关上并且域也相同,那么也许您可以在您的 environment.ts 中跳过 window.location.origin:

export const environment = {
   ...
   togglesUrl: '/release-toggling',...
};
,

显然问题在于该值是在编译时解决的。您可以尝试使用 togglesUrl: () => window.location.origin 之类的函数,然后从代码中调用它。

就我个人而言,我看不出您需要使用这种方法的任何理由。这不会给您带来任何好处。如果您直接使用 my/request 之类的内容调用您的服务,这将自动解析为当前域。

另一种选择是直接在服务中解析源,或者更好的方法是创建一个 HttpInterceptor,它会在运行时修补请求 URL。

附言您提前知道了 URL,因此您可以轻松地在一开始就定义正确的 URL,而不必玩弄位置。

,

我认为除了在您的环境中存储域之外,您还需要使用其他方法。

一些选项:

  1. 使用相对 URL 例如:this.http.get('/someUrl') 在这种情况下,请求是针对当前域进行的。
  2. 使用代理供本地使用。 Docs
  3. 在您的环境中使用静态网址
  4. 使用 location.prepareExternalUrl docs
  5. 可能是组合