2017-08-06 5 views
2

私はアプリケーションをAngular 4で書いています。角度になると、APIにアクセスしようとするたびに2つのリクエストが出ます。これは、私のアプリ全体のすべてのメソッドで発生します。 GET、DELETE、PUT、POSTAngularはhttpリクエストを2回送信します

以下にいくつかのコードサンプルを追加します。たとえば、データベースからの通知をリストするNotificationComponentがあります。 NotificationComponentにはngOnInitの通知をロードするメソッドがあります。

this.NotificationService.All(AdditionalParams) 
     .subscribe(
      notifications => { 
       this.AllNotifications.Notifications = notifications.data; 
       this.AllNotifications.Data = notifications; 
       this.AllNotifications.Loading = false; 
       this.AllNotifications.Loaded = true; 
       this.AllNotifications.HasRequestError = false; 
      }, 
      (error)=> { 
       this.AllNotifications.Loading = false; 
       this.AllNotifications.Loaded = false; 
       this.AllNotifications.RequestStatus = error.status; 
       if (typeof error.json == 'function' && error.status!=0) { 
       let errorObject = error.json(); 
       this.AllNotifications.RequestError = errorObject; 
       } else { 
       this.AllNotifications.RequestError = "net::ERR_CONNECTION_REFUSED"; 
       } 
       this.AllNotifications.HasRequestError = true; 
      }); 
    } 

メソッドは、NotificationServiceにあるAllメソッドにサブスクライブします。 Allメソッドは次のようになります。

All(AdditionalParams: object): Observable<any> { 
    let options = new RequestOptions({ headers: this.headers }); 
    let params = new URLSearchParams(); 
    //params.set("token", this.authenticationService.token); 
    for (var key in AdditionalParams) { 
     params.set(key, AdditionalParams[key]); 
    } 
    options.params = params; 
    return this.http.get(this.notificationsUrl, options) 
     .map(response => response.json()) 
     .catch(this.handleError); 
    } 

何とかリクエストが2回送信されます。私はこれを私のコンソールのログで考えます。

XHR finished loading: GET "[REMOVED]/notifications?page=1&event=1&token=eyJ0eXAiOi…GkiOiJ1bGYxSnJPa1Zya0M2NmxDIn0.3kA8Pd-tmOo4jUinJqcDeUy7mDPdgWpZkqd3tbs2c8A" 
XHR finished loading: GET "[REMOVED]/notifications?page=1&event=1&token=eyJ0eXAiOi…GkiOiJ1bGYxSnJPa1Zya0M2NmxDIn0.3kA8Pd-tmOo4jUinJqcDeUy7mDPdgWpZkqd3tbs2c8A" 

約3秒離れています。

「AuthenticationService」というサービスがあります。このサービスでは、ng-http-interceptorを使用してhttpインターセプタを追加しました。 httpインターセプタはすべてのリクエストに追加されます。それはこのように見えます。

httpInterceptor.request().addInterceptor((data, method) => { 
      console.log ("Before httpInterceptor: ", data); 
      var RequestOptionsIndex = null; 
      for (var _i = 0; _i < data.length; _i++) { 
       if (typeof data[_i] == 'object' && data[_i].hasOwnProperty('headers')){ 
        RequestOptionsIndex = _i; 
       } 
      } 
      if (RequestOptionsIndex == null) { 
       let options = new RequestOptions({headers: new Headers({'Content-Type': 'application/json'})}); 
       let params = new URLSearchParams(); 
       data.push(options); 
       RequestOptionsIndex = data.length-1; 
      } 
      //console.log (data, this.loginURL, 'RequestOptionsIndex: ', RequestOptionsIndex); 
      if (!data[RequestOptionsIndex].hasOwnProperty('headers')){ 
       data[RequestOptionsIndex].headers = new Headers({'Content-Type': 'application/json'}); 
      } 
      if (data[0]!=this.loginURL && (data[RequestOptionsIndex].headers.get('Authorization')=="" || data[RequestOptionsIndex].headers.get('Authorization')==null)) { 
        data[RequestOptionsIndex].headers.append("Authorization", 'Bearer ' + this.token); 
      } 
      if (data[RequestOptionsIndex].params!=undefined && data[RequestOptionsIndex].params!=null) { 
       data[RequestOptionsIndex].params.set('token', this.token); 
      }else { 
       let params = new URLSearchParams(); 
       params.set('token', this.token); 
       data[RequestOptionsIndex].params = params; 
      } 
      console.log ("httpInterceptor data", data, ": RequestOptionsIndex", RequestOptionsIndex); 
      return data; 
     }); 
     httpInterceptor.response().addInterceptor((res, method) => { 
      res.map(response => response.json()) 
       .catch((err: Response, caught: Observable<any>) => { 
        if (err.status === 401) { 
         this.logout(); 
         this.router.navigate(["/login"]); 
         location.reload(); 
         return Observable.throw("401 Unauthorized"); 
        } 
        return Observable.throw(caught); // <----- 
       }).subscribe() 
      return res; 
     }); 

答えて

1

私はそれ私のhttpInterceptor.response().addInterceptor削除.subscribe()フィックスで応答に加入していることに気づい質問を投稿しながら。だからそれはなる。

httpInterceptor.response().addInterceptor((res, method) => { 
      return res.map(response => response) // => response.json() 
       .catch((err: Response, caught: Observable<any>) => { 
        if (err.status === 401) { 
         this.logout(); 
         this.router.navigate(["/login"]); 
         location.reload(); 
         return Observable.throw("401 Unauthorized"); 
        } 
        return Observable.throw(caught); // <----- 
       })//.share().subscribe() 
      //return res; 
     }); 

誰かがこのように愚かな間違いを犯した場合のケースです。これが私の解決策でした。

問題は複数回リクエストを購読すると発生し、複数回実行されます。解決策は、要求を共有したり、一度購読したりすることです。うまくいけば、誰かがこれを確認することなく、複数の購読を要求を共有する正確な方法についてはわかりません。私は.share().subscribe()を試しましたが、私にとってはうまくいかなかったようです。

+0

"401 Unauthorized"が発生した場合、私は購読していません。これを解決する方法はありますか? – LogicDev

+1

結果にresを代入する 'res = res.map'を追加すると、' catch'を持つobservableは返されません。それは意味をなさないか、別に答える必要がありますか? – 0mpurdy

+0

@ 0mpurdy私もそう思った。私のコードを更新し、それは働いた。私は私の答えも更新しました。 – LogicDev

関連する問題