如何在Angular2中重定向到外部URL?

294

在Angular 2中,将用户重定向到完全外部的URL的方法是什么?例如,如果我需要重定向用户到OAuth2服务器以进行身份验证,我该如何做?

Location.go()Router.navigate()Router.navigateByUrl()可以用于将用户发送到Angular 2应用程序中的另一个部分(路由),但我看不出它们如何用于重定向到外部网站?


10
注意:如果您的外部URL不包含http://或https://,Angular 4将把该URL视为内部路由。以防其他人遇到同样的问题。 - aherocalledFrog
哇,这个线程太有趣了。想象一下解释Angular的好处,然后再解释如何导航到外部URL。预计需要1小时的努力。 - AlxVallejo
16个回答

344
你可以使用以下代码:window.location.href = '...';来改变页面到你想要的任何位置。

3
呃,我不知道为什么尝试将其调用为一个函数而不是直接更改值。直接设置该值可以正常工作。 - Michael Oryl
12
记住,直接引用窗口会限制您的代码只能在具有窗口对象的平台上运行。 - ender
2
@ender 难道没有其他替代方案吗?也许有一些情况我们真的想要重定向到外部链接。当然,我们可以使用 window.location.href,但正如你所说,它也有缺点。如果在 Angular 中有支持的 API,那会更好。 - Krishnan
1
当然可以,但这适用于99%运行javascript并需要进行页面重定向的所有平台。即使是phantom/casperJs也尊重窗口对象。您可以调用document.location.href或甚至Location.href,因为它们都指向同一个对象。 位置引用 - Dennis Smolek
2
@DennisSmolek 但是如果你试着使用Universal将其编译成安卓应用程序,这种行为不会失败吗? - ender
显示剩余10条评论

219
一个 Angular 的方法是导入 @angular/common (或在 Angular < 4 中使用 @angular/platform-browser)中的 DOCUMENT,并使用它来实现先前描述的方法。
document.location.href = 'https://stackoverflow.com';

在一个函数内部。

some-page.component.ts

import { DOCUMENT } from '@angular/common';
...
constructor(@Inject(DOCUMENT) private document: Document) { }

goToUrl(): void {
    this.document.location.href = 'https://stackoverflow.com';
}

some-page.component.html

<button type="button" (click)="goToUrl()">Click me!</button>

请查看platformBrowser代码库以获取更多信息。


6
在 Angular 4 中,应该从 @angular/common 导入 DOCUMENT(例如 import { DOCUMENT } from '@angular/common';),否则这个功能非常好用!请参见 https://github.com/angular/angular/blob/master/packages/platform-browser/src/dom/dom_tokens.ts。 - John
4
使用 @Inject(DOCUMENT) private document: any 有什么目的? - Sunil Garg
3
在单元测试中,注入“DOCUMENT”使得用模拟对象替换文档对象更加容易。同时,它也允许在其他平台(服务器/移动设备)上使用另一种实现方式。 - eppsilon
5
为了严格类型检查,我使用constructor(@Inject(DOCUMENT) private document: Document) { } - Ian Jamieson
我遇到了错误:ERROR NullInjectorError: R3InjectorError(AppModule)[Document -> Document -> Document]: NullInjectorError: No provider for Document! - Sami
显示剩余3条评论

45

解决方案正如Dennis Smolek所说,是非常简单的。将window.location.href设置为您要切换到的URL,它就可以正常工作。

例如,如果您在组件类文件(控制器)中有以下方法:

goCNN() {
    window.location.href='http://www.cnn.com/';
}

然后在模板中使用相应的 (click) 调用,你可以很简单地通过一个按钮(或其他任何元素)来完成:

<button (click)="goCNN()">Go to CNN</button>

33

我认为你需要添加目标属性为 "_blank" ,这样你就可以使用window.open

gotoGoogle() : void {
     window.open("https://www.google.com", "_blank");
}

17

如果你一直在使用OnDestry生命周期钩子,那么在调用window.location.href=...之前,你可能会对像这样的内容感兴趣。

    this.router.ngOnDestroy();
    window.location.href = 'http://www.cnn.com/';

这将会触发你组件中的OnDestry回调函数,这可能是你所喜欢的。

哦,还有:

import { Router } from '@angular/router';

这里是你找到路由器的地方。

---编辑--- 不幸的是,我可能在上面的示例中错了。至少现在在我的生产代码中没有按预期工作 - 因此,直到我有时间进一步调查,我会像这样解决它(因为我的应用程序真的需要尽可能使用钩子)

this.router.navigate(["/"]).then(result=>{window.location.href = 'http://www.cnn.com/';});

基本上是将路由定向到任何(虚拟的)路由以触发钩子,然后按请求导航。


非常感谢这个解决方案。我已经寻找了一段时间的解决方案,只能在新标签页上打开外部链接,但是在同一标签页上,所有的window.open、location.pathname/href等都无法让我从我的网站导航离开。 这是处理从Angular应用程序中路由出去的最干净和正确的方式! - EranKT

13

在较新版本的Angular中,使用any作为窗口对象。

(window as any).open(someUrl, "_blank");

最佳答案 - Victor Bredihin
2
Angular最新版本不允许使用普通的window吗? - Justin

8

有两个选项:

  1. if you want to redirect in same window/tab

     gotoExternalDomain(){
         window.location.href='http://google.com/'
     }
    
  2. if you want to redirect in new tab

     gotoExternalDomain(){
         (window as any).open("http://google.com/", "_blank");
     }
    

2
你好!你能解释一下 "_blank" 是什么意思吗?因为即使没有它,链接也可以在新标签页中打开。 - tz0
@tz0 它会在新标签页中打开一个URL。 - Co ti
@Coti 但它打开了那个URL,而且没有使用“_blank”。 - tz0
在其他浏览器中可能需要"_blank"。但是例如最新版的Chrome不需要这个规范,而其他浏览器会将其定义为"_self"->将会在同一个标签页中重定向。 - Rejja Kubzek

5
在将我的头撕下来后,解决方案只是在href中添加http://。
<a href="http://www.URL.com">Go somewhere</a>

8
你需要回答什么问题? - Guido Flohr
@GuidoFlohr 我有一个表单,人们需要输入一个链接,有时他们会输入 'www.someLink.com',这种情况下由于缺少前缀 'http',重定向会出现问题。所以这个答案是正确的。 - Nitneq
@Nitneq 这个问题是关于在Angular中重定向的。而答案与问题毫无关系。 - Guido Flohr
有时候,Angular 不是问题所在。 - Nitneq

5

1
对我而言,这只是改变了URL,而应用程序状态并没有改变(实际路由看起来一样)。即使“location.replaceState('/')”也没有像我期望的那样起作用。“router.navigate(['/']);”才是让我成功的关键。 - Matt Rowles
2
Angular 2的Location似乎不适用。文档指出,Location的目的是“根据应用程序的基本href规范化URL。”使用它来重定向到应用程序内的URL可能是合适的;但是使用它来重定向到外部URL似乎与文档不符。 - J. Fritz Barnes

5
你可以使用多种方式进行重定向:
例如:
window.location.href = 'redirect_url';

另一种 Angular 文档方式:

从 Angular 中导入 document,必须注入文档,如下所示,否则将会出现错误。

import { DOCUMENT  } from '@angular/common';
export class AppComponent {
     constructor(
       @Inject(DOCUMENT) private document: Document
    ) {}
   this.document.location.href = 'redirect_url';
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接