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


173

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

Location.go(),,Router.navigate()Router.navigateByUrl()可以将用户发送到Angular 2应用程序内的另一个区域(路线),但是我看不到如何将其用于重定向到外部站点?


4
您难道不容易做到这一点可笑吗?必须有一种更简单的方法来执行此操作,而不必为此编写代码。
Maccurt

3
注意:如果您的外部URL不包含http://或https://,则Angular 4会将URL视为内部路由。万一其他人为此感到挣扎。
ahero所谓的青蛙

Answers:


214

您可以使用此-> window.location.href = '...';

这会将页面更改为您想要的任何内容。


3
gh,由于某些原因,我尝试将其称为函数,而不仅仅是更改其值。直接设置该值有效。
Michael Oryl 2015年

9
请记住,直接引用窗口会将您的代码限制在带有window对象的平台上。
渲染者

2
@ender没有替代品吗?在某些情况下,我们确实希望重定向到外部链接。当然,我们可以使用window.location.href,但正如您所说,它有其缺点。如果Angular中有受支持的API,那会更好。
克里希南

1
可以,但这是运行javascript并需要进行页面重定向的所有平台的99%。甚至幻像/棺材也尊重窗口对象。您可以调用document.location.href甚至Location.href它们都引用相同的对象。位置参考
Dennis Smolek '17

2
@DennisSmolek但是,如果您尝试使用Universal将其编译为android应用,这种行为不会失败吗?
ender

124

前面描述的方法的Angular方法是DOCUMENT从Angular <4 导入@angular/common(或@angular/platform-browser在Angular <4中)并使用

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>

查看PlateformBrowser存储库以获取更多信息。


目标站点是否知道请求来自我们的应用程序,因为此处的要求是为了登录目的而重定向,因此SSO应用程序应在成功后重定向回我们的应用程序
NitinSingh

5
在角度4中,应该从@angular/common(即import { DOCUMENT } from '@angular/common';)导入DOCUMENT ,但否则效果很好!见github.com/angular/angular/blob/master/packages/...
约翰

4
以这种方式注入文档的目的是什么@Inject(DOCUMENT) private document: any
Sunil Garg

1
@SunilGarg注入DOCUMENT使在单元测试中用模拟替换文档对象更加容易。它还允许在其他平台(服务器/移动设备)上使用替代实现。
eppsilon

3
对于严格类型我使用,constructor(@Inject(DOCUMENT) private document: Document) { }
伊恩·贾米森

38

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

例如,如果您的组件的类文件(控制器)中有此方法:

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

然后,您可以通过(click)在模板中的按钮(或其他按钮)上进行适当的调用来相当简单地调用它:

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

21

我认为您需要àtarget =“ _ blank”,因此可以使用window.open

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

10

如果您一直在使用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/';});

基本上路由到任何(虚拟)路由以强制挂接,然后根据请求进行导航。



3

扯掉我的头后,解决方案是将http://添加到href。

<a href="http://www.URL.com">Go somewhere</a>

4
您对此有何疑问?
Guido Flohr


1

我使用Angular 2 Location做到了这一点,因为我自己不想操纵全局窗口对象。

https://angular.io/docs/ts/latest/api/common/index/Location-class.html#!#prepareExternalUrl-anchor

可以这样完成:

import {Component} from '@angular/core';
import {Location} from '@angular/common';
@Component({selector: 'app-component'})
class AppCmp {
  constructor(location: Location) {
    location.go('/foo');
  }
}

1
对我来说,这只是更改了URL,而应用程序的状态却没有改变(实际路由看起来一样)。甚至'location.replaceState('/')也不像我预期的那样起作用。router.navigate(['/']);对我来说是什么
马特·罗尔斯

2
Angular 2 Location听起来不适用。文档指出位置的目的是:“位置负责根据应用程序的基本href标准化URL。” 使用它重定向到应用程序内的URL可能是合适的;使用它重定向到外部URL似乎不适合文档。
J. Fritz Barnes

1

以上所有解决方案均不适用于我,我只是添加了

window.location.href = "www.google.com"
event.preventDefault();

这对我有用。

或尝试使用

window.location.replace("www.google.com");

0

在你的component.ts中

import { Component } from '@angular/core';

@Component({
  ...
})
export class AppComponent {
  ...
  goToSpecificUrl(url): void {
    window.location.href=url;
  }

  gotoGoogle() : void {
    window.location.href='https://www.google.com';
  }
}

在您的component.html中

<button type="button" (click)="goToSpecificUrl('http://stackoverflow.com/')">Open URL</button>
<button type="button" (click)="gotoGoogle()">Open Google</button>

<li *ngFor="item of itemList" (click)="goToSpecificUrl(item.link)"> // (click) don't enable pointer when we hover so we should enable it by using css like: **cursor: pointer;**
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.