200个触发器的HTTP请求" catch" Angular 5中的操作

时间:2018-02-13 07:32:34

标签: javascript angular rest

我有一个用Java编写的REST登录操作(用于服务器端)。 JWT也被使用。

客户端正在使用Angular 5下的HTTP客户端来访问/执行REST API。

正在发生的是登录REST功能(使用HTTP客户端)被执行。之后,返回信息并返回代码状态为200(意味着一切正常)。

根据Chrome浏览器"网络"选项卡,RC返回200。

即使是这种情况,"赶上"语句(与REST登录调用相关联)始终执行。

下面列出了代码。

我做错了什么?

TIA

来自浏览器的信息

enter image description here

控制台日志

admin-services.service.ts:208 TypeError: Cannot read property 'json' of null
    at MapSubscriber.eval [as project] (admin-services.service.ts:176)
    at MapSubscriber._next (map.js:79)
    at MapSubscriber.Subscriber.next (Subscriber.js:91)
    at MapSubscriber._next (map.js:85)
    at MapSubscriber.Subscriber.next (Subscriber.js:91)
    at FilterSubscriber._next (filter.js:90)
    at FilterSubscriber.Subscriber.next (Subscriber.js:91)
    at MergeMapSubscriber.notifyNext (mergeMap.js:151)
    at InnerSubscriber._next (InnerSubscriber.js:25)
    at InnerSubscriber.Subscriber.next (Subscriber.js:91)
(anonymous) @ admin-services.service.ts:208
CatchSubscriber.error @ catchError.js:105
MapSubscriber._next @ map.js:82
Subscriber.next @ Subscriber.js:91
MapSubscriber._next @ map.js:85
Subscriber.next @ Subscriber.js:91
FilterSubscriber._next @ filter.js:90
Subscriber.next @ Subscriber.js:91
MergeMapSubscriber.notifyNext @ mergeMap.js:151
InnerSubscriber._next @ InnerSubscriber.js:25
Subscriber.next @ Subscriber.js:91
onLoad @ http.js:2270
ZoneDelegate.invokeTask @ zone.js:425
onInvokeTask @ core.js:4744
ZoneDelegate.invokeTask @ zone.js:424
Zone.runTask @ zone.js:192
ZoneTask.invokeTask @ zone.js:499
invokeTask @ zone.js:1540
globalZoneAwareCallback @ zone.js:1566
XMLHttpRequest.send (async)
scheduleTask @ zone.js:2933
ZoneDelegate.scheduleTask @ zone.js:411
onScheduleTask @ zone.js:301
ZoneDelegate.scheduleTask @ zone.js:405
Zone.scheduleTask @ zone.js:236
Zone.scheduleMacroTask @ zone.js:259
(anonymous) @ zone.js:2966
proto.(anonymous function) @ zone.js:1366
(anonymous) @ http.js:2366
Observable._trySubscribe @ Observable.js:172
Observable.subscribe @ Observable.js:160
subscribeToResult @ subscribeToResult.js:23
MergeMapSubscriber._innerSub @ mergeMap.js:138
MergeMapSubscriber._tryNext @ mergeMap.js:135
MergeMapSubscriber._next @ mergeMap.js:118
Subscriber.next @ Subscriber.js:91
ScalarObservable._subscribe @ ScalarObservable.js:51
Observable._trySubscribe @ Observable.js:172
Observable.subscribe @ Observable.js:160
MergeMapOperator.call @ mergeMap.js:92
Observable.subscribe @ Observable.js:157
FilterOperator.call @ filter.js:61
Observable.subscribe @ Observable.js:157
MapOperator.call @ map.js:57
Observable.subscribe @ Observable.js:157
MapOperator.call @ map.js:57
Observable.subscribe @ Observable.js:157
CatchOperator.call @ catchError.js:80
Observable.subscribe @ Observable.js:157
AdminLoginComponent.onSubmit @ admin-login.component.ts:80
(anonymous) @ AdminLoginComponent.html:19
handleEvent @ core.js:13581
callWithDebugContext @ core.js:15090
debugHandleEvent @ core.js:14677
dispatchEvent @ core.js:9990
(anonymous) @ core.js:12332
schedulerFn @ core.js:4351
SafeSubscriber.__tryOrUnsub @ Subscriber.js:239
SafeSubscriber.next @ Subscriber.js:186
Subscriber._next @ Subscriber.js:127
Subscriber.next @ Subscriber.js:91
Subject.next @ Subject.js:56
EventEmitter.emit @ core.js:4319
NgForm.onSubmit @ forms.js:5751
(anonymous) @ AdminLoginComponent.html:19
handleEvent @ core.js:13581
callWithDebugContext @ core.js:15090
debugHandleEvent @ core.js:14677
dispatchEvent @ core.js:9990
(anonymous) @ core.js:10611
(anonymous) @ platform-browser.js:2628
ZoneDelegate.invokeTask @ zone.js:425
onInvokeTask @ core.js:4744
ZoneDelegate.invokeTask @ zone.js:424
Zone.runTask @ zone.js:192
ZoneTask.invokeTask @ zone.js:499
invokeTask @ zone.js:1540
globalZoneAwareCallback @ zone.js:1566
core.js:1427 ERROR Error: Unexpected Error Code: undefined
    at CatchSubscriber.eval [as selector] (admin-services.service.ts:216)
    at CatchSubscriber.error (catchError.js:105)
    at MapSubscriber._next (map.js:82)
    at MapSubscriber.Subscriber.next (Subscriber.js:91)
    at MapSubscriber._next (map.js:85)
    at MapSubscriber.Subscriber.next (Subscriber.js:91)
    at FilterSubscriber._next (filter.js:90)
    at FilterSubscriber.Subscriber.next (Subscriber.js:91)
    at MergeMapSubscriber.notifyNext (mergeMap.js:151)
at InnerSubscriber._next (InnerSubscriber.js:25)

管理-services.service.ts

[... snip ...]

  adminLogin(username, password): Observable<boolean> {
    let url = `${this._apiRoot}/login`;
    let tokenResp = {};

    return this.http.post(url, JSON.stringify({ username: username, password: password }))
      .map((response: Response) => {

        // login successful if there's a token in the response
        let token = response.json() && response.json().token;

        if (token) {

          let t = JWT(token);

          console.log("-- what is in the token --");
          console.log(t);

          //initiialize
          let setUser: User = ANONYMOUS_USER;

          // need to set the value here
          this.userLoggedIn.next(setUser);

          // store username and jwt token in local storage to keep user logged in between page refreshes
          // => SET BACK: localStorage.setItem('currentUser', JSON.stringify(this.userLoggedIn));
          // => SET BACK: this.userLoggedIn = JSON.parse(localStorage.getItem('currentUser'));

          // return true to indicate successful login
          return true;
        } else {
          // throw an error that the token was "whack"
          return Observable.throw(
            new Error("APX: the token was not set properly"));
        }
        //return response.json();
      })
      .catch(e => {
        console.error(e);

        if (e.status === 401) {
          return Observable.throw(
            new Error("Error Code : 401 - Unauthorized Access To Server "));
        }

        return Observable.throw(
          new Error( "Unexpected Error Code: " + e.status ));
      });
  }
[... snip ...]

更新 没有回应。

登录正在使用JWT。该信息作为标题的一部分返回。

Authorization:Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXJyZW5jZWRhcmJ5IiwiaWQiOjQ4LCJ0ZW5hbnRpZCI6MjU2LCJrZXlpZCI6MCwidXNlcm5hbWUiOiJ0ZXJyZW5jZWRhcmJ5IiwiZW1haWxhZGRyIjoidGVycmVuY2VAZGFyYnkuY29tIiwicm9sZSI6MSwiZmlyc3RuYW1lIjoidGVycmVuY2UgIiwibGFzdG5hbWUiOiJkYXJieSIsImV4cCI6MTUxODUwNTcwMX0.FNlvx-3WePXWEoqkDLfMw3GkkNcy_S-V3TcikBTfzOo

更新

代码

return this.http.post(url, JSON.stringify({ username: username, password: password }))
      .map((response: Response) => {

        console.log( "==>  looking for the answer - begin ");
        console.log( response );
        console.log( "==>  looking for the answer - end ");

生成的值

NgForm {submitted: true, _directives: Array(2), ngSubmit: EventEmitter, form: FormGroup}control: (...)controls: (...)dirty: (...)disabled: (...)enabled: (...)errors: (...)form: FormGroup {validator: null, asyncValidator: null, _onCollectionChange: ƒ, pristine: false, touched: true, …}formDirective: (...)invalid: (...)ngSubmit: EventEmitter {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}path: (...)pending: (...)pristine: (...)status: (...)statusChanges: (...)submitted: truetouched: (...)untouched: (...)valid: (...)value: (...)valueChanges: (...)_directives: (2) [NgModel, NgModel]__proto__: ControlContainer
admin-login.component.ts:72  getting ready to go call the service 
admin-login.component.ts:76  values for id and password terrencedarby ----- 3333333333
admin-services.service.ts:175 ==>  looking for the answer - begin 
admin-services.service.ts:176 null
admin-services.service.ts:177 ==>  looking for the answer - end 

2 个答案:

答案 0 :(得分:1)

问题在于以下代码

    // login successful if there's a token in the response
    let token = response.json() && response.json().token;

    if (token) {
    ...
    }

新的angular 5 httpClient默认返回JSON对象,因为响应对象上的.json()调用是多余的。如果您在尝试将其解析为json之前添加响应本身的console.log,则可以确切地看到返回的对象。

更新: 由于标题包含令牌,您可以像这样提取它,

let token = res.headers.get("Authorization");

答案 1 :(得分:1)

由于您使用的是Angular 5,因此您应该考虑使用HttpClient而不是旧的已弃用的http。

要获得标题,您需要两件事

  1. 您需要指定&#39;观察:&#39;响应&#39;在请求选项中 (见https://angular.io/guide/http#reading-the-full-response
  2. 如果您的后端与前端不在同一个域中,则需要“暴露”&#39;这些标头,使用后端的Access-Control-Expose-Headers标头
  3. 所以你的服务器响应应该有那个标题

    Access-Control-Expose-Headers: Authorization
    

    (见https://stackoverflow.com/a/48306230/1160794

    这是修改后的代码

    adminLogin(username, password): Observable<boolean> {
    let url = `${this._apiRoot}/login`;
    let tokenResp = {};
    
    //to post json with HttpClient
    const headers = new HttpHeaders({'Content-Type':'application/json; charset=utf-8'})
    
    return this.http.post(url, JSON.stringify({ username: username, password: password }), headers)
      .map((response: HttpResponse) => {
    
        // login successful if there's a token in the response
        let token = response.header.get('Authorization');
    
        if (token) {
    
          let t = JWT(token);
    
          console.log("-- what is in the token --");
          console.log(t);
    
          //initiialize
          let setUser: User = ANONYMOUS_USER;
    
          // need to set the value here
          this.userLoggedIn.next(setUser);
    
          // store username and jwt token in local storage to keep user logged in between page refreshes
          // => SET BACK: localStorage.setItem('currentUser', JSON.stringify(this.userLoggedIn));
          // => SET BACK: this.userLoggedIn = JSON.parse(localStorage.getItem('currentUser'));
    
          // return true to indicate successful login
          return true;
        } else {
          // throw an error that the token was "whack"
          return Observable.throw(
            new Error("APX: the token was not set properly"));
        }
        //return response.json();
      })
      .catch(e => {
        console.error(e);
    
        if (e.status === 401) {
          return Observable.throw(
            new Error("Error Code : 401 - Unauthorized Access To Server "));
        }
    
        return Observable.throw(
          new Error( "Unexpected Error Code: " + e.status ));
      });
    

    }