Angular2 Http Call没有开火

时间:2017-02-07 08:27:58

标签: javascript angularjs ajax angular typescript

背景:

在几个教程之后,我正在使用Angular2和JWT测试身份验证。我带来了一个组件和服务:

app.component.ts
user.service.ts

应用程序组件(和模板)包含对显示用户登录状态的observable的订阅。 Observable项保存在用户服务中,并在用户登录和注销时更改(正常)。

身份验证令牌写在" localStorage" as" auth_token"。它包含一个有效值(时间),应强制用户在一段时间后再次登录。

我想做的是在app init上检查令牌有效性。首先,我尝试从user.service CONSTRUCTOR,然后(失败),我尝试从app.component中的ngOnInit,然后(再次失败),我试图在事件调用(点击一个按钮)来自应用程序组件,但再次失败!

一些缩短的代码:

//app.component.html
//...
    <a md-button class="app-icon-button" aria-label="checklogin" (click)="checkLogin()">
        <md-icon svgIcon="check"></md-icon>
    </a>
//...

//app.component.ts
//...
    checkLogin(){
        console.log('CHECK LOGIN FUNCTION');
        let token = localStorage.getItem('auth_token');
        if(token){
            console.log('TOKEN FOUND');
            this.userService.checkToken(token);
        }else{
            console.log('NO TOKEN FOUND');
        }
    }
//...

//user.service.ts
//...
    checkToken(token){
        console.log('CHECK TOKEN FUNCTION');
        console.log('TOKEN : '+token);
        let headers = new Headers();
        headers.append('Content-Type','application/json');
        return this.http
            .post(
                '/url/script.php',
                JSON.stringify(token),
                { headers }
            )
            .map(res => res.json())
            .map((res) => {
                console.log('SCRIPT RESULT : ');
                if(res.valid){
                    console.log('TOKEN IS VALID');
                    return true;
                }else{
                    console.log('TOKEN NOT VALID');
                    return false;
                }
            });
    }
//...

我确实跳过了可观察的部分和订阅。

问题:

问题实际上是应用程序永远不会调用脚本!

当我点击&#34; checkLogin&#34;按钮(当存在令牌时),

console shows 'CHECK LOGIN FUNCTION',
console shows 'TOKEN FOUND',
console shows 'CHECK TOKEN FUNCTION',
console shows 'TOKEN : '****************************** (token),

但它从未显示过“SCRIPT RESULT&#39;”, 当使用firebug检查http调用是否完成时,对script.php没有任何调用。貌似this.http部分只是被忽略了......

感谢您阅读/帮助

4 个答案:

答案 0 :(得分:1)

使用Observables的Ajax调用仅在您拥有subscriber时才有效。

所以你需要subscribe到那个Observable。这是Angular 2功能。当您没有订阅Observable时,它将永远不会拨打该电话。

而且您也不需要从订阅者处返回任何内容,因为您实际上无法返回任何内容。

this.userService.checkToken(token).subscribe((res) => {
   console.log('SCRIPT RESULT : ');
   if(res.valid) {
      console.log('TOKEN IS VALID');          
   } else {
      console.log('TOKEN NOT VALID');
   }
});

checkToken(token){
   console.log('CHECK TOKEN FUNCTION');
   console.log('TOKEN : '+token);
   let headers = new Headers();
   headers.append('Content-Type','application/json');
   return this.http
       .post(
           '/url/script.php',
           JSON.stringify(token),
           { headers }
       )
       .map(res => res.json());           
}

答案 1 :(得分:1)

当订阅仅在消费者使用.subscribe方法订阅输出结果时使用时,服务才开始工作。

您需要:this.userService.checkToken(token).subscribe()

答案 2 :(得分:1)

您的checkToken()方法返回Observable所需的subsrcibe。除非它订阅,否则观察者永远不会执行。

checkLogin(){
        console.log('CHECK LOGIN FUNCTION');
        let token = localStorage.getItem('auth_token');
        if(token){
            console.log('TOKEN FOUND');
            this.userService.checkToken(token).subscribe(result => {
               console.log(result); 
            }),
            error => { 
               console.log(error); 
            });
        } else {
            console.log('NO TOKEN FOUND');
        }
    }

答案 3 :(得分:1)

您是否尝试使用Postman并尝试调用所需的功能?

另外,如果angular2-jwt可以为您执行此操作,为什么需要验证令牌?

你可以这样做:

使用angular2-jwt安装npm

加入app.module.ts

import { AUTH_PROVIDERS } from 'angular2-jwt';

添加到提供者:

providers: [
    AUTH_PROVIDERS,
],

例如auth.service.ts如下所示:

import { Injectable, Inject }                                               from '@angular/core';
import { Http, Response, Headers, RequestOptions, RequestMethod }           from '@angular/http';
import { Router }                                                           from '@angular/router';

import { Observable }                                                       from 'rxjs/Observable';
import { Configuration }                                                    from '../../app.config';

import { RegisterViewModel }                                                from '../../model/viewModel/registerViewModel';
import { LoginViewModel }                                                   from '../../model/viewModel/loginViewModel';

import { tokenNotExpired, AuthHttp }                                        from 'angular2-jwt';

@Injectable()
export class AuthService {

private actionUrl: string; 

constructor(private _http: Http, private _config: Configuration, private _router: Router, private _authHttp: AuthHttp){
    this.actionUrl = _config.apiUrl;
}

register(user: RegisterViewModel){
    let headers = new Headers({ 'Content-Type': 'application/json' });
    //Admin in this system can only register users. that is why auth
    return this._authHttp.post(this.actionUrl + '/Account/Register', JSON.stringify(user), { headers : headers })
        .do(response => {
            console.log(response.toString());
        });
}

login(user: LoginViewModel) {
    let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
    return this._http.post('http://localhost:56181/api/token', "username=" + user.userName + "&password=" + user.password + "&userId=" + user.userId, { headers : headers })
        .do(response => {
            if(response){
                let authResult = response.json();
                this.setUser(authResult);
                this._router.navigate(['']);
            }
        });
}

public isAuthenticated(): boolean {
    //angular2-jwt has this function to check if token is valid
    return tokenNotExpired();
}

private setUser(authResult: any): void {
    localStorage.setItem('id_token', authResult.id_token);
}

public logout(): void {
    localStorage.removeItem('id_token');
    this._router.navigate(['']);
}

}

还要记住angular2-jwt localstorage中的令牌默认名称为id_token,否则您必须使用angular2-jwt帮助类来指定其他令牌名称。

您可以通过以下方式检查它是否正常工作:

app.component.ts中的

export class AppComponent { 
constructor(private _auth: AuthService){
}
}

app.component.html

 <li>
 <a class="nav-link" [routerLink]="['/login']" *ngIf="!_auth.isAuthenticated()">Login</a>
 </li>
 <li>
 <a class="nav-link" (click)="_auth.logout()" *ngIf="_auth.isAuthenticated()">Log Out</a>
 </li>

你也可以在以下网址阅读一些文档:

https://auth0.com/blog/introducing-angular2-jwt-a-library-for-angular2-authentication/