Angular 模块中的 window.location.origin 为空
Posted
技术标签:
【中文标题】Angular 模块中的 window.location.origin 为空【英文标题】:window.location.origin is null in Angular module 【发布时间】:2021-06-12 19:28:18 【问题描述】:我有一个应用程序和一个库,两个独立的存储库。我的应用使用了我的库,而我的库包含一个执行 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
]
;
我的 App 的 environment.ts 如下所示:
export const environment =
...
togglesUrl: window.location.origin + '/release-toggling',
...
;
在我的 App 的 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 在这一点上实际上是空的。在你的forRoot
函数中,你可以console.log(window.location.origin)
和console.log(config.togglesUrl)
【参考方案1】:
所有应用都通过网关提供服务,并位于同一个 window.location.origin。
如果两个应用程序都在同一个网关上,并且域也相同,那么也许您可以跳过 environment.ts 中的 window.location.origin:
export const environment =
...
togglesUrl: '/release-toggling',
...
;
【讨论】:
那行不通,因为如果我在example.com/deep/in/my/app,它会相对尝试这样做,而 window.location.origin 会给我网关 url (example.com)【参考方案2】:显然问题在于该值是在编译期间解析的。您可以尝试使用 togglesUrl: () => window.location.origin
之类的函数,然后从代码中调用它。
我个人认为没有任何理由需要使用这种方法。这对您没有任何好处。如果您直接使用 my/request
之类的名称调用您的服务,这将自动解析到当前域。
另一种选择是直接在服务中解析来源,或者更好的方法是创建一个 HttpInterceptor,它会在运行时修补请求 URL。
附:您事先知道 URL,因此您可以在开始时轻松定义正确的 URL,而不是玩 Location。
【讨论】:
【参考方案3】:我认为除了将域存储在环境中之外,您还需要使用其他东西。
一些选项:
-
使用相对 URL 例如:
this.http.get('/someUrl')
在这种情况下,请求是针对当前域的。
为本地使用使用代理。 Docs
在您的环境中使用静态 URL
使用location.prepareExternalUrl
docs
可能是组合
【讨论】:
以上是关于Angular 模块中的 window.location.origin 为空的主要内容,如果未能解决你的问题,请参考以下文章
angular.module()创建获取注册angular中的模块