使用 Angular2 从 url 检索哈希片段

问题描述 投票:0回答:10

鉴于这个 url 结构(我无法控制),我如何使用 Angular2 检索哈希片段?

http://your-redirect-uri#access_token=ACCESS-TOKEN

我的路由器确实路由到正确的组件,但

oauth
之后的所有内容都被废弃,我在 request.params 或 location.path 中找不到哈希片段。注定??

路由器配置:

@RouteConfig([
{path: '/welcome', name: 'Welcome', component: WelcomeComponent, useAsDefault: true},
{path: '/landing/oauth', name: 'Landing', component: LandingComponent}  // this one

])

typescript angular2-routing
10个回答
81
投票

对于那些仍在寻找的人:

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

export class MyComponent {

  constructor(
    private route: ActivatedRoute,
  ) { }

  myfunction(){
    this.route.fragment.subscribe((fragment: string) => {
        console.log("My hash fragment is here => ", fragment)
    })
  }
}

20
投票

为了扩展当前的答案,我想找到一种简单的方法来解析哈希中的查询参数(特别是对于联合响应),因为

ActivatedRoute
似乎无法本地处理该问题。

this.route.fragment.subscribe(fragment => {
  const response = _.fromPairs(Array.from(new URLSearchParams(fragment)));
  response.access_token;
  response.id_token;
  response.expires_in;
  response.token_type;
});

首先使用片段创建一个新的 URLSearchParams 对象来查询其值:

new URLSearchParams(fragment).get('access_token');

对于大多数情况,这可能是所需要的全部,但如果需要将其转换为对象,

Array.from
URLSearchParams
转换为数组数组,如下所示:
[['key', 'value'], ...]
。然后 lodash 的
_.fromPairs
将其转换为对象。


14
投票

您还可以使用ActivatedRouteSnapshot,无需订阅其上的所有更改。

@Component({templateUrl:'./my-component.html'})
class MyComponent {
  constructor(route: ActivatedRoute) {
    const fragment: string = route.snapshot.fragment;
  }
}

5
投票

我已经接受了 nwayve 的评论并使用 RxJS 管道实现了它,如下所示:

this.route.fragment
  .pipe(
    map(fragment => new URLSearchParams(fragment)),
    map(params => ({
      access_token: params.get('access_token'),
      id_token: params.get('id_token'),
      error: params.get('error'),
    }))
  )
  .subscribe(res => console.log('', res));

2
投票

假设您在构造函数中使用 ActivatedRoute 类,请尝试以下操作:

let params = this.route.snapshot.fragment;

const data = JSON.parse(
    '{"' +
        decodeURI(params)
            .replace(/"/g, '\\"')
            .replace(/&/g, '","')
            .replace(/=/g, '":"') +
        '"}'
);

console.log(data); // { json: "with your properties"}

1
投票

我也遇到了同样的问题,用

response_type
=
token
请求 OAuth 服务器,谁重定向到
%REDIRECT_URI%#access_token=:access_token&token_type=:token_type&expires_in=:expires_in

问题是,默认情况下,不会路由对子网址的直接访问:在您的情况下,

%BASE_URL%/landing/oauth
不会重定向到
LandingComponent
组件。

我用这个配置修复了它:

import { bootstrap } from '@angular/platform-browser-dynamic';
import { provide } from '@angular/core';
import { APP_BASE_HREF } from '@angular/common';
import { ROUTER_PROVIDERS } from '@angular/router';

import { AppComponent } from './components/app/app.component';

bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    provide(APP_BASE_HREF, { useValue: '/' }) // this line
]);

1
投票

使用纯 JavaScript 解析片段数据的选项是

this.activatedRoute.fragment.subscribe(value => {
  let fragments = value.split('&')
  let fragment = {}
  fragments.forEach(x => {
    let y = x.split('=')
    fragment[y[0]] = y[1]
  })
})

信息将以易于访问的对象的形式存在。


1
投票

我尝试了这个,但快照是一个空字符串。 https://stackoverflow.com/a/51286916/569302

这对我有用:

  ngOnInit(): void {
    this.route.fragment.subscribe({ 
        next: value => {
        if (value === null) {
          throw new Error('not implemented');
        }
        const access_token = new URLSearchParams(value).get('access_token')
        console.log({access_token})
      }
    });
  }

0
投票

您可以随时使用以下代码检索 url 片段 - 该代码利用了

Router
服务:

const urlTree = this.router.parseUrl(this.router.url);
console.log(urlTree.fragment); //access_token=ACCESS-TOKEN

0
投票

这是唯一对我有用的“仅角度”解决方案(

import { NavigationEnd, Router } from '@angular/router';
...

constructor(
    private router: Router,) {}
...

ngOnInit() { 
    this.router.events.subscribe((event) => {
      if(event instanceof NavigationEnd) {
        console.log("route change url", event.url)
      }
    });
}

从 URL http://localhost:8100/#/activity 打印 /activity

© www.soinside.com 2019 - 2024. All rights reserved.