如何在角度 5 中获取基本 url?

Posted

技术标签:

【中文标题】如何在角度 5 中获取基本 url?【英文标题】:How to get base url in angular 5? 【发布时间】:2019-01-29 17:49:35 【问题描述】:

我当前的网址是http://localhost:4200/test/dashboard。

我想使用 Angular 5 功能打印基本网址,即http://localhost:4200。

【问题讨论】:

***.com/questions/36222845/…的可能重复 【参考方案1】:

不需要特定角度的功能,window.location.origin 会为您完成。

【讨论】:

这个答案对于大多数情况来说可能是完美的。但是,如果您已将基本 href 设置为 / 以外的其他内容,或者您​​需要支持更复杂的情况,那么还有很多附加选项。有关这些的详细信息,请参阅this answer。【参考方案2】:

PlatformLocation 提供有关 URL 的更多详细信息:

import PlatformLocation  from '@angular/common';

 constructor(platformLocation: PlatformLocation) 
  console.log((platformLocation as any).location);
  console.log((platformLocation as any).location.href);
  console.log((platformLocation as any).location.origin);

【讨论】:

这违背了使用 PlatformLocation 的目的。如果 Angular 不在浏览器中运行,这将中断。 documentation for PlatformLocation 表示“不应由应用程序开发人员直接使用。相反,应使用 Location。”请参阅my answer 了解Location 以及一系列替代方案。【参考方案3】:

console.log(位置);

console.log(location.href);

获取基本网址:console.log(location.origin);

【讨论】:

【参考方案4】:

您可以从“通用”包中导入“位置”:

import  Component, OnInit  from '@angular/core';
import  Location  from '@angular/common'; // <--- Here
import  Router  from '@angular/router';

@Component(
  selector: 'some-component',
  templateUrl: './component.html',
  styleUrls: ['./component.scss']
)
export class SomeComponent implements OnInit 

  constructor(location: Location) 

  ngOnInit() 
        console.log(this.location.origin);  // <--- Use Here
  


【讨论】:

此位置对象中没有“原点” 该类的属性来源不存在。【参考方案5】:

您可以尝试(可以获取当前位置的所有详细信息)

import  Component, OnInit  from '@angular/core';
import  Location  from '@angular/common';

@Component(
 selector: 'some-component',
 templateUrl: './component.html',
 styleUrls: ['./component.scss']
)

export class SomeComponent implements OnInit 

 constructor(location: Location) 

    ngOnInit() 
        console.log(this.location._platformStrategy._platformLocation.location);  
    

【讨论】:

【参考方案6】:

我使用了 Rotemya 的回答中的位置,如下所示

import  Location  from '@angular/common';

constructor(public location: Location)  

但是 this.location.origin 对我不起作用。所以我使用了this.location.path.name

 ngOnInit() 
        console.log(this.location.path.name);
  

【讨论】:

【参考方案7】:

这对我不起作用(Angular 7):

this.location.path.name

但我发现可以从文档中获取:

import  Inject  from '@angular/core';
import  DOCUMENT  from '@angular/common';

constructor(@Inject(DOCUMENT) private document: Document) 
    const origin = this.document.location.origin;

【讨论】:

【参考方案8】:
import  DOCUMENT, LocationStrategy  from '@angular/common';


@Injectable()
export class SomeService 
  constructor(@Inject(DOCUMENT) private readonly document: any,
    private readonly locationStrategy: LocationStrategy) 

  // for localhost: http://localhost:4200/someBaseHref
  getUrl(): string 
    return `$this.document.location.origin/$this.locationStrategy.getBaseHref()`
  


【讨论】:

【参考方案9】:

这里的其他答案涵盖了相当多的选项:

location window.location document.location DOCUMENT / Document Location LocationStrategy PlatformLocation

TLDR; 对于简单的情况,全球可用的 DOM location 可能足以满足您的需求。但是,您可能真的想要一个 Angular Location 实例。而且,在某些情况下,LocationStrategy 也可能有用。

您可以直接访问 DOM location 而无需导入任何内容:

foo(): void 
  console.log(location.origin);
  console.log(location.href);
  console.log(location.pathname);

如果您想使用 Angular LocationLocationStrategy,那么您必须像这样将它们拉入:

import  Location, LocationStrategy  from '@angular/common';

constructor(private location: Location, private locationStrategy: LocationStrategy)  

foo(): void 
  console.log(this.location.path());
  console.log(this.location.prepareExternalUrl('/'));
  console.log(this.locationStrategy.getBaseHref());

您可以使用prepareExternalUrl 来表示,例如构建引用资产的 URL:

const url = this.location.prepareExternalUrl('assets/svg/icons.svg');

如果您直接在 / 下提供所有内容,使用 Angular Location 似乎没有多大意义,但如果您将应用程序的基本 href 设置为 / 以外的其他内容,或者如果您正在使用路径做更复杂的事情,那么 Angular Location 将帮助您正确处理此类事情。

如果 prepareExternalUrl 似乎没有选择您的基本 href,请参阅此答案末尾的相关说明。

在某些示例中,您会看到它声明您必须配置APP_BASE_HREF 才能获取您的基本href。现在不再是这种情况了,有关更多信息,请参阅此答案的结尾。

注意:默认情况下,Angular 使用定位策略PathLocationStrategy,但如果您更改为使用HashLocationStrategy,那么prepareExternalUrl 和其他功能将无法以相同的方式工作。但是,如果您使用的是HashLocationStrategy,您可能知道自己在做什么,所以我不会在这里讨论。

完整的细节

让我们依次看看上面列出的每个实体。

1. locationwindow.locationdocument.location 的类型为 Location,直接来自 DOM,可作为全局变量使用,即您不必导入或以任何方式注入它们。

这些都是达到同一目的的所有方法。 locationwindow.location 在字面上是同一个东西(window 可以显式引用,但它也是隐式全局 this)。 locationdocument.location本质上是一回事,请参阅 SO answer 了解更多详情。

您可以找到 Location here 的 MDN 文档。

所以如果 DOM Location 是你想要的,我会使用 location。有些人喜欢明确表示他们正在访问window 对象,并且更喜欢使用window.locationdocumentlocation 字段有一段令人困惑的历史,似乎是访问 DOM Location 实例的最不流行的方式。

2. 在其他地方,您可以看到人们使用 Angular 依赖注入令牌 DOCUMENT,如下所示:

import  DOCUMENT  from '@angular/common';
import  Inject  from '@angular/core';

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

然后您可以访问this.document.location。同样,这只是一个 DOM Location 实例,所以如果这是您想要的,当您可以直接以 location 访问它时,为什么还要麻烦注入它呢?上面提到的this.document 和全局可用的document 都是Document 类型,并且在浏览器上下文中,它们是同一个东西。因此,您注入它的唯一原因是您在非浏览器上下文中工作。

您可以找到 DOCUMENT here 的 Angular 文档和 Document here 的 MDN 文档。

3. 最后三个 Angular 实体 - LocationLocationStrategyPlatformLocation

令人困惑的是,Angular 使用与上面的 location 等类型相同的名称作为其位置类型(即Location)。 DOM Location 全局可用,不需要导入,Angular Location 需要从@angular/common 导入。

Angular 实体LocationLocationStrategyLocationStrategy 相互叠加,Location 包含LocationStrategyLocationStrategy 又包含PlatformLocation。它们都没有直接暴露包含的实体,即您无法通过Location API 访问LocationStrategy,也无法通过LocationStrategy 访问PlatformLocation

您会看到许多直接访问 PlatformLocation 的旧示例,但正如其 documentation 所明确指出的那样,这个“类应该由应用程序开发人员直接使用。”

结论

所以我们从一个令人困惑的实体数组开始,但最后,它实际上只是归结为在 DOM 提供的全局 location 对象和 Angular 提供的 Location 对象之间进行选择。在某些情况下,LocationStrategy 也可能感兴趣。

代码

但是,如果您想要更深入地了解,为什么不试试下面的代码,它会引入提到的每一个实体。查看控制台输出以查看每个实体提供的内容,并尝试使用每个实体的 API。为简单起见,只需将此代码添加到现有组件之一:

import  Inject  from '@angular/core';
import  DOCUMENT, Location, LocationStrategy, PlatformLocation  from '@angular/common';

// Normally, you should not access PlatformLocation directly, it's just included here for completeness.
constructor(@Inject(DOCUMENT) private document: Document, private location: Location, private locationStrategy: LocationStrategy, private plaformLocation: PlatformLocation)  

ngOnInit(): void 
    // These are just different ways to get the same thing, so if this
    // is what want, you might as well use plain location directly.
    console.log('DOM location', location)
    console.log('DOM window.location', window.location)
    console.log('DOM document.location', document.location)
    console.log('Injected document.location', this.document.location)

    // These are layered on top of each other. A Location contains a
    // LocationStrategy and a LocationStrategy contains a PlatformLocation.
    // Note that this.location, used here, is a different thing to plain location above.
    console.log('location', this.location)
    console.log('locationStrategy', this.locationStrategy)
    console.log('platformLocation', this.plaformLocation) // PlatformLocation "should not be used directly by an application developer."

在浏览器中打开您的应用,然后查看开发人员工具中的控制台输出,看看您是否找到了所需的内容。

注意:在 Angular 世界中,事情很快就会变得陈旧 - 以上都在 Angular 9 中运行良好。

基本 href 和 Location

如果您有一个没有路由的简单应用程序,并且您将基本 href 设置为 / 以外的其他值,那么您可能会发现像 prepareExternalUrl 这样的函数无法考虑基本 href。如果您没有在app.module.tsimports 部分中包含RouterModule,则会发生这种情况。无论出于何种原因,Location 下的LocationStrategyPlatformLocation 仅在导入RouterModule 时才能正确配置。要解决这个问题,只需添加以下内容:

imports: [
  ...
  RouterModule.forRoot([]),
  ...
]

即使您没有指定任何路由,即传入[],这也会正确配置事物以考虑您的基本href。

APP_BASE_HREFPlatformLocationLocation

在某些示例中,您会看到它声明您必须显式配置APP_BASE_HREF 才能获取您的基本href。例如。就像app.module.ts

providers: [
  provide: APP_BASE_HREF,
  useFactory: (pl: PlatformLocation) => pl.getBaseHrefFromDOM(),
  deps: [PlatformLocation]
]

这个可能在某个阶段是必要的,但是当前的PathLocationStrategy 代码会自动为您执行此操作,即如果您不设置APP_BASE_HREF,那么它会自行检索基本 href 值使用PathLocationStrategygetBaseHrefFromDOM() 方法。你可以在PathLocationStrategyconstructor逻辑中看到这个here。

【讨论】:

迄今为止我读过的关于整个基本 href 主题的最佳解释和总结。为我解决了许多问题。非常感谢。

以上是关于如何在角度 5 中获取基本 url?的主要内容,如果未能解决你的问题,请参考以下文章

从重定向角度 5 中获取查询参数

如何在 Web API 控制器中获取基本 URL?

如何在基本href之后启动角度路由器而不更改资产地址

如何在 CodeIgniter 2.* 中获取基本 url

如何在角度 5 中绑定角度材料下拉列表的数据?

在 Selenium IDE 中,如何获取基本 url 的值