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

时间:2016-03-25 15:28:05

标签: angular

我需要向同一台服务器发出请求,在另一个端口上停止api。

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

9 个答案:

答案 0 :(得分:46)

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

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

有关详细信息,请参阅此完整工作Stackblitz Angular sample

更新了Angular 6 +的答案

正如其他人所说,原来的答案不再适用。对于Angular 6+,您需要提供Injection Token,以便window - 对象可以在AOT - build中解析。

我建议在单独的文件中创建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
]

可以将WINDOW_PROVIDERS常量添加到providers中的AppModule数组中,如下所示:

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

SampleService中,可以使用定义的Injection Token注入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;
    }
}

Angular 2的原始答案

因此,您需要在引导应用程序时设置Window - 对象的提供程序。

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

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

constructor(private window: Window) {
   var hostname = this.window.location.hostname;
}

答案 1 :(得分:19)

另一种选择是使用@ 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' );
}

答案 2 :(得分:10)

Angular 2 最新工作解决方案:

app.module.ts

providers: [
    {provide: Window, useValue: window},
    ...
]

youclass.ts

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

答案 3 :(得分:6)

您可以使用window,如其他人所述,并且要使其从ng6起可以注入,您需要注入令牌。

像这样声明令牌:

export const WINDOW = new InjectionToken('window',
    { providedIn: 'root', factory: () => window }
);

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

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

由于Window是TypeScript中的一个接口,如果不这样进行注入,则在构建生产项目时会出现错误:Can't resolve all parameters for <ClassName>。 然后是另一个:ERROR in : Error: Internal error: unknown identifier undefined

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

答案 4 :(得分:4)

我使用app.component.ts中的以下代码实现了它:

import { Component, OnInit, Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

    constructor(@Inject(DOCUMENT) private document: any) { }

    ngOnInit() {
        this.domain = this.document.location.hostname;
        console.log(this.domain);
    }
}

这应该在您的控制台中打印域名。

答案 5 :(得分:4)

我建议使用window.location,正如其他人所说的那样。

但是,您也可以通过导入Angular的常用位置&#39;来实现此目的。库,并在注射器中使用它,如:

import { Injectable } from '@angular/core';
import { Location }   from '@angular/common';
const otherPort = 8000;

@Injectable()
export class ServiceOrComponentName {
  constructor(location: Location) {
    this.baseUrl = location._platformStrategy._platformLocation._location.protocol +
      '//' + location._platformStrategy._platformLocation._location.hostname +
      ':' + otherPort;
  }
}

答案 6 :(得分:4)

我在Angular 7上进行了测试,并且正常工作

declare var window: any;

console.log (window.location.host); //result lrlucas.github.io > domain github pages

使用window.location.host,我可以获得完整的域

注意:在@Component之前声明窗口变量

答案 7 :(得分:1)

只需注入文档。 Angular 有一个默认的 Document 实现。 Document 有一个名为 defaultView 的属性,它具有窗口之类的所有优点。

import { DOCUMENT } from '@angular/common';
import { Inject, Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class HostnameService
{

  constructor(
    @Inject(DOCUMENT) private document: Document
  ) { }

  getHostname(): string
  {
    // Remember to use this.document as unscoped document also exists but is not mockable.
    return this.document.defaultView.window.location.hostname;

    // Or use the location on document.
    return this.document.location.hostname;

  }
}

其他地方不需要设置。

答案 8 :(得分:0)

我正在使用普通的javascript和URL native api进行URL解析:

const parsedUrl = new URL(window.location.href);
const baseUrl = parsedUrl.origin;
console.log(baseUrl); // this will print http://example.com or http://localhost:4200