Angular2获取url查询参数

Posted

技术标签:

【中文标题】Angular2获取url查询参数【英文标题】:Angular2 get url query parameters 【发布时间】:2017-02-01 19:04:39 【问题描述】:

我正在为我的 Angular2 网络应用程序设置 Facebook 注册。 一旦应用程序通过 Facebook 接受(在被重定向到 Facebook 授权页面之后),它就会重定向到我的 webapp,并将令牌和代码作为 url 参数:

http://localhost:55976/?#access_token=MY_ACCESS_TOKEN&code=MY_CODE

但是一旦页面被加载,参数就会被删除。网址变成:

http://localhost:55976/

如何在参数(access_token 和代码)被删除之前提取它们? 我的路由配置包含:

 path: 'login', component: LoginComponent ,
 path: 'login/:access_token/:code', component: LoginComponent ,

编辑:

这是我在 login.component 中重定向到 facebook 的方式: html:

<a class="btn btn-social btn-facebook socialaccount_provider facebook" title="Facebook" href="#" (click)="login_facebook()">
    <span class="fa fa-facebook"></span> <span style="padding-left:25px">Sign in with Facebook</span>
</a>

打字稿:

login_facebook() 
    let url = 'https://www.facebook.com/dialog/oauth?'+
        'client_id=my_client_id' +
        '&redirect_uri=' + encodeURIComponent('http://localhost:55976/#/login/') +
        '&response_type=code%20token';
    console.log(url);
    window.location.href = url;

facebook api 重定向到http://localhost:55976/#/login/,这是我尝试获取 access_token 和代码参数的地方。

编辑 2:

如果我删除重定向 url 中的尖角,facebook 会将我重定向到正确的 URL,但没有尖角,角度无法解析 url。

在删除“#”之前:

redirect_uri: http://localhost:55976/#/login/
facebook return: http://localhost:55976/?#access_token=MY_ACCESS_TOKEN&code=MY_CODE

删除“#”后:

redirect_uri: http://localhost:55976/login/
facebook return: http://localhost:55976/login/?#access_token=MY_ACCESS_TOKEN&code=MY_CODE

这意味着问题来自尖锐。但如果没有尖锐的角度,则会返回 HTTP 错误 404.0 - Not Found。

【问题讨论】:

【参考方案1】:

在this 帖子中查看我的答案。

[更新] 似乎有些版主删除了我的答案,说它是重复的答案。但我不同意,因为我根据每个问题发布了相关代码 sn-ps。直到这个答案没有被取消,我再次在这里发布答案的一部分。如果您同意,请投票取消删除我的回答。


使用window.location.hash 访问从# 开始的所有参数。 或者您可以使用window.location.href 访问完整的 URL。 要获取令牌,您可以使用window.location.hash.match(/#access_token=([^&amp;]+)/)[1]

注意:如果您使用的是 TypeScript,那么您需要在组件中导入窗口。

declare let window;

【讨论】:

【参考方案2】:

这对我有用! :)

import  ActivatedRoute  from '@angular/router'; 

constructor(private route: ActivatedRoute)  

/** usage in the method */
let projectId = this.route.snapshot.queryParams.projectId;

【讨论】:

【参考方案3】:
getQueryParams( locationSearch: string):any 
    let params = ;
    if( locationSearch ) 
        locationSearch = locationSearch.split('?')[1];
        let splited = locationSearch.split('&');
        for( let i = 0; i < splited.length; i++ ) 
            let propName = splited[i].split('=')[0];
            let propValue = splited[i].split('=')[1];
            params[propName] = propValue;
        
    

    return params;


let q = getQueryParams( location.search );

【讨论】:

【参考方案4】:

使用 javascript

(new URL(location)).searchParams.get("parameter_name")

【讨论】:

这对我来说几乎是完美的。但是在构建打字稿时出现此错误:“位置”类型的参数不可分配给“字符串”类型的参数 URL 构造函数需要一个字符串作为第一个参数,但位置是 Location。 new URL(location.href) 会起作用。 对于那些在 Observables 中遇到时间问题的人。【参考方案5】:

这是我的最终工作代码:

进口:

import  Router, NavigationCancel  from '@angular/router';
import  URLSearchParams,  from '@angular/http';

构造函数:

 constructor(public router: Router) 
    router.events.subscribe(s => 
      if (s instanceof NavigationCancel) 
        let params = new URLSearchParams(s.url.split('#')[1]);
        let access_token = params.get('access_token');
        let code = params.get('code');
      
    );
  

【讨论】:

您使用的是哪种定位策略?我也有您在上述评论中遇到的问题:哈希片段在我可以访问之前已被删除..您是否管理它以使用 hashlocationstrategy 或它仅适用于 html5 pathlocationstrategy? 我正在使用 html5 路径定位策略。我不确定,但我认为它只适用于这种策略。 是的,我确认,这仅适用于 pathlocationstrategy +1 表示正确答案。我通常不让自己咆哮,但这是我想的正确答案,是的,想象一下......在纯 JS 中它需要一行,而在 Angular 中它需要导入、订阅等。太多而很少做。【参考方案6】:

您正在从ActivatedRoute 寻找query parameters。

要接收它们,您可以将它们放入组件的 OnInit 函数中,如下所示:

private accesstoken;
private code;

constructor(private route: ActivatedRoute)  

ngOnInit() 
  // Capture the access token and code
  this.route
      .queryParams
      .subscribe(params => 
          this.accesstoken = params['#access_token'];
          this.code = params['code'];
      );

  // do something with this.code and this.accesstoken

我在上面的链接中有更多示例。你可能有角度的问题,因为路由器也识别片段,以#开头...如果角度确实将它识别为片段,那么你可以订阅从ActivatedRoute 观察到的片段并这样做。

我不确定您是否被重定向。如果是,可以考虑使用preserveQueryParams 导航选项,类似这样。

this.router.navigate([redirect], preserveQueryParams: true);

【讨论】:

感谢您的回复。参数仍然是空的。我已经尝试使用来自 ActivatedRoute 的可观察片段,但它并没有改变任何东西。我没有被重定向。重定向是由 facebook api 进行的。我已更新主帖以添加更多详细信息。 嗯。对我来说,问题似乎是 facebook 正在重定向到 localhost:55976/?#access_token=MY_ACCESS_TOKEN&code=MY_CODE,而您想重定向到 localhost:55976/#/login/…。也许 facebook 正在重定向到错误的组件? 是的,你是对的,问题似乎来自 facebook 重定向。我已经更新了我的帖子。问题是没有'#'的重定向。 您可以通过使用PathLocationStrategy 而不是HashLocationStrategy 将angular2 更改为不带# 的工作。但是 PathLocationStrategy 已经是 angular2 中的默认值,因此您可能会在某处覆盖它。您提供路线的主要模块是什么样的?见here for more info。 你是对的,PathLocatinoStrategy 设置为 HashLocationStrategy。但是当我将其设置为 PathLocationStrategy 时,每次尝试使用 url 访问页面(而不是导航)时都会出现 404 错误。【参考方案7】:

你试过了吗?

import  Params, Router  from '@angular/router';


     constructor(private router: Router) 

            this.route.params.forEach((params: Params) => 
            //here you can get your params
            let param = params['parameterName'];


            )
        

【讨论】:

感谢您的回复。 this.route.params 变量为空。当我尝试使用 console.log(JSON.stringify(params)); 记录它时它返回“” 知道为什么哈希在我可以访问之前就被删除了吗?

以上是关于Angular2获取url查询参数的主要内容,如果未能解决你的问题,请参考以下文章

Angular2路由器2.0.0在加载不同参数的相同url时不重新加载组件?

如何从Angular2中的父组件获取子路由的:id参数

Angular 2新表单,提交重定向到同一页面,表单字段附加在URL中作为查询参数,新路由器版本

Angular 2 - 如何传递 URL 参数?

如何处理角度2中的查询参数

类型上不存在 Angular2 属性