【问题标题】:Intercept each http calls an ES6 approach拦截每个http调用一个ES6方法
【发布时间】:2017-10-20 05:36:52
【问题描述】:

我想在 Angular 中编写可以拦截所有 ajax 调用的可注入服务。基本上在 ajaxStart 之前和完成之后。我可以通过这个code-sn-ps来实现。但我可以使用 es5 语法来实现它。我怎样才能通过扩展文件号:3 中显示的XMLHttpRequest 来做同样的事情?

1) http-interceptor.ts

import { Injectable, Component, OnInit } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

interface AjaxRequest {
    url?: string;
    requestCount?: number;
    method?: string;
}

interface AjaxResponse {
    url?: string;
    requestCount?: number;
    response?: string;
}

@Injectable()
export class HttpInterceptor {

    public ajaxStart = new BehaviorSubject<AjaxRequest>({});
    public ajaxStop = new BehaviorSubject<AjaxResponse>({});

    constructor() {
        this.bootstrapAjaxInterceptor();
    }

    private bootstrapAjaxInterceptor() {

        const _self = this;
        const originalOpen = XMLHttpRequest.prototype.open;

        XMLHttpRequest.prototype.open = function (xhrMethod, requestUrl) {

            _self.ajaxStart.next(requestUrl);

            this.addEventListener('readystatechange', xhr => {

                _self.ajaxStop.next(this.responseURL);

            }, false);

            originalOpen.apply(this, arguments);
        };
    }
}

2) 应用组件.ts

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

    constructor(private httpInterceptor: HttpInterceptor) { }

    ngOnInit() {

        this.httpInterceptor.ajaxStart.subscribe(url => {
            console.log('ajaxStart : ', url);
        });

        this.httpInterceptor.ajaxStop.subscribe(url => {
            console.log('ajaxStop : ', url);
        });
    }
}

3) http-interceptor.ts

@Injectable()
export class HttpInterceptor extends XMLHttpRequest {

    open(xhrMethod, requestUrl) {
        // Equivalent to XMLHttpRequest.prototype.open
        // Now how to handle `readystatechange`
    }

    ajaxStart() { }

    ajaxStop() { }
}

【问题讨论】:

  • 感谢@Bahrampour 的更正。如果你觉得这是个好问题。你可以投票吗?

标签: javascript angularjs dependency-injection ecmascript-6


【解决方案1】:

也许是这样的?

class HttpInterceptor extends XMLHttpRequest {
  onreadystatechange = () => {
    switch (this.readyState) {
      case 1:
        this.ajaxStart();
        break;
      case 4:
        this.ajaxStop();
        break;
    }
  }

  ajaxStart() {
    console.log('operation started.');
  }

  ajaxStop() {
    console.log('operation completed.');
  }
}

const interceptor = new HttpInterceptor();

interceptor.open('GET', 'https://developer.mozilla.org/');
interceptor.send();

【讨论】:

  • 无法通过 DI 以角度或 const interceptor = new HttpInterceptor(); 初始化它会抛出 ERROR TypeError: Failed to construct 'XMLHttpRequest': Please use the 'new' operator, this DOM object constructor cannot be called as a function
  • 嗨@dork,您的回答给了我一些提示,因此您很赞成,但仍在寻找正确的解决方案。如果您觉得这是一个好问题,请为我的问题投票以快速获得答案。
猜你喜欢
  • 2015-03-04
  • 1970-01-01
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多