te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Angular sends an http request twice - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular sends an http request twice - Stack Overflow

programmeradmin4浏览0评论

I have written an app in Angular 4. And it looks like angular makes 2 requests each time I try to access an API. This happens for all methods across my app including; GET, DELETE, PUT, POST

I will add some code sample below. For example I have a NotificationComponent that lists a ll notifications from the database. The NotificationComponent has a method which loads the notifications on 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;
            });
  }

The method subscribes to the All method found in the NotificationService. The All method looks like this;

  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);
  }

Somehow the request is sent twice. I think this in my console log;

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"

About 3 seconds apart.

I have a service called "AuthenticationService". In this service I have added an http interceptor using ng-http-interceptor. The http interceptor gets added to all requests. And it looks like this;

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;
        });

I have written an app in Angular 4. And it looks like angular makes 2 requests each time I try to access an API. This happens for all methods across my app including; GET, DELETE, PUT, POST

I will add some code sample below. For example I have a NotificationComponent that lists a ll notifications from the database. The NotificationComponent has a method which loads the notifications on 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;
            });
  }

The method subscribes to the All method found in the NotificationService. The All method looks like this;

  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);
  }

Somehow the request is sent twice. I think this in my console log;

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"

About 3 seconds apart.

I have a service called "AuthenticationService". In this service I have added an http interceptor using ng-http-interceptor. The http interceptor gets added to all requests. And it looks like this;

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;
        });
Share Improve this question asked Aug 6, 2017 at 17:05 user5500750user5500750
Add a ment  | 

1 Answer 1

Reset to default 13

While posting the question I noticed that I was subscribing to the response in my httpInterceptor.response().addInterceptor Removing .subscribe() fixes it. So it bees;

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;
        });

Just in case someone makes a silly mistake like this. This was my solution.

The problem happens when you subscribe to a request more than once, so it gets executed multiple times. The solution is to share the request or subscribe to it once. I am not sure about the exact way to share a request multiple subscriptions without reloading hopefully someone will confirm this. I tried .share().subscribe() but didn't seem to work for me.

发布评论

评论列表(0)

  1. 暂无评论