如何在角度 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 forPlatformLocation
表示“不应由应用程序开发人员直接使用。相反,应使用 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 Location
和 LocationStrategy
,那么您必须像这样将它们拉入:
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. location
、window.location
和 document.location
的类型为 Location
,直接来自 DOM,可作为全局变量使用,即您不必导入或以任何方式注入它们。
这些都是达到同一目的的所有方法。 location
和 window.location
在字面上是同一个东西(window
可以显式引用,但它也是隐式全局 this
)。 location
和 document.location
本质上是一回事,请参阅 SO answer 了解更多详情。
您可以找到 Location
here 的 MDN 文档。
所以如果 DOM Location
是你想要的,我会使用 location
。有些人喜欢明确表示他们正在访问window
对象,并且更喜欢使用window.location
。 document
的 location
字段有一段令人困惑的历史,似乎是访问 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 实体 - Location
、LocationStrategy
和 PlatformLocation
。
令人困惑的是,Angular 使用与上面的 location
等类型相同的名称作为其位置类型(即Location
)。 DOM Location
全局可用,不需要导入,Angular Location
需要从@angular/common
导入。
Angular 实体Location
、LocationStrategy
和LocationStrategy
相互叠加,Location
包含LocationStrategy
,LocationStrategy
又包含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.ts
的imports
部分中包含RouterModule
,则会发生这种情况。无论出于何种原因,Location
下的LocationStrategy
和PlatformLocation
仅在导入RouterModule
时才能正确配置。要解决这个问题,只需添加以下内容:
imports: [
...
RouterModule.forRoot([]),
...
]
即使您没有指定任何路由,即传入[]
,这也会正确配置事物以考虑您的基本href。
APP_BASE_HREF
、PlatformLocation
和 Location
在某些示例中,您会看到它声明您必须显式配置APP_BASE_HREF
才能获取您的基本href。例如。就像app.module.ts
:
providers: [
provide: APP_BASE_HREF,
useFactory: (pl: PlatformLocation) => pl.getBaseHrefFromDOM(),
deps: [PlatformLocation]
]
这个可能在某个阶段是必要的,但是当前的PathLocationStrategy
代码会自动为您执行此操作,即如果您不设置APP_BASE_HREF
,那么它会自行检索基本 href 值使用PathLocationStrategy
的getBaseHrefFromDOM()
方法。你可以在PathLocationStrategy
的constructor
逻辑中看到这个here。
【讨论】:
迄今为止我读过的关于整个基本 href 主题的最佳解释和总结。为我解决了许多问题。非常感谢。以上是关于如何在角度 5 中获取基本 url?的主要内容,如果未能解决你的问题,请参考以下文章