如何在Angular2中获取服务的域名

Пав*_*ков 33 angular

我需要向同一个服务器发出请求,在另一个端口上休息api.

如果不在服务URL中硬编码全名,我怎么能这样做呢?

M.E*_*.E. 51

不需要特定于角度2的解决方案.您可以使用它window.location.hostname来获取当前主机名.

但是,请注意,如果您不想直接使用window-object 等全局变量,则可以提供自己的Window对象,然后可以将其注入.

有关详细信息,请参阅此完整工作的Stackblitz Angular示例.

更新了Angular 6+的答案

正如其他人所说,原来的答案不再适用.对于Angular 6+,您需要提供注入令牌,以便window可以在AOT -build中解析-object.

我建议WINDOW_PROVIDERS在单独的文件中创建一个数组,如下所示:

import { InjectionToken, FactoryProvider } from '@angular/core';

export const WINDOW = new InjectionToken<Window>('window');

const windowProvider: FactoryProvider = {
  provide: WINDOW,
  useFactory: () => window
};

export const WINDOW_PROVIDERS = [
    windowProvider
]
Run Code Online (Sandbox Code Playgroud)

WINDOW_PROVIDERS常数可以被添加到providers在该阵列AppModule是这样的:

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    WINDOW_PROVIDERS, // <- add WINDOW_PROVIDERS here
    SampleService,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

SampleService,window可以使用定义的注入令牌注入对象,如下所示:

import { Injectable, Inject } from '@angular/core';
import { WINDOW } from '../window.provider';

@Injectable()
export class SampleService {

    constructor(@Inject(WINDOW) private window: Window) {
    }

    getHostname() : string {
        return this.window.location.hostname;
    }
}
Run Code Online (Sandbox Code Playgroud)

Angular 2的原始答案

因此,您需要Window在引导应用程序时为-object 设置提供程序.

import {provide} from 'angular2/core';
bootstrap(..., [provide(Window, {useValue: window})]);
Run Code Online (Sandbox Code Playgroud)

之后,您可以使用window对象并访问主机名,如下所示:

constructor(private window: Window) {
   var hostname = this.window.location.hostname;
}
Run Code Online (Sandbox Code Playgroud)

  • 使用自己的Window对象与使用全局常量有什么好处?谢谢 (5认同)
  • 这将不再适用于 Angular 6。您将收到“无法解析所有参数”的错误消息。要完成这项工作,您必须声明一个注入令牌,然后在构造函数中使用它。我将添加一个答案以使其更加明确。 (2认同)

Thi*_*ibs 25

另一个选择是使用@ angular/platform-b​​rowser中的DOCUMENT.

import {DOCUMENT} from '@angular/platform-browser';

constructor(@Inject(DOCUMENT) private document: Document) {
    let url = document.location.protocol +'//'+ document.location.hostname + ':my_port' );
}
Run Code Online (Sandbox Code Playgroud)

  • 或者你可以只使用“document.location.origin” (2认同)

Mar*_*rfu 10

Angular 2 最新工作解决方案:

app.module.ts

providers: [
    {provide: Window, useValue: window},
    ...
]
Run Code Online (Sandbox Code Playgroud)

youclass.ts

constructor(
    @Inject(Window) private _window: Window
) {
    this._baseUrl = `http://${this._window.location.hostname}:3333`;
};
Run Code Online (Sandbox Code Playgroud)


gia*_*ise 8

我使用普通的 javascript 和URL 本机 api进行 URL 解析:

declare var window: any; // Needed on Angular 8+
const parsedUrl = new URL(window.location.href);
const baseUrl = parsedUrl.origin;
console.log(baseUrl); // this will print http://example.com or http://localhost:4200
Run Code Online (Sandbox Code Playgroud)

  • 这在 Angular 8 上不起作用,但是如果你使用 ````declare var window: any;```` 那么它就可以工作 (2认同)

Gio*_*ssi 6

您可以window像其他人所说的那样使用并使其可注射,从ng6开始,您需要一个注射令牌.

像这样声明令牌:

export const WINDOW = new InjectionToken('window',
    { providedIn: 'root', factory: () => window }
);
Run Code Online (Sandbox Code Playgroud)

然后在类构造函数中使用它:

class Foo {
  constructor(@Inject(WINDOW) private window: Window) { }
}
Run Code Online (Sandbox Code Playgroud)

WindowTypeScript中的接口一样,如果您不进行这样的注入,那么当您为生产构建项目时,您将收到错误:Can't resolve all parameters for <ClassName>.后来又一个:ERROR in : Error: Internal error: unknown identifier undefined.

要更好地理解注射,请阅读DI的角度文档:https: //angular.io/guide/dependency-injection