Angular / Zone.js:如何正确拦截非Angular的XMLHttpRequest?

huangapple go评论73阅读模式
英文:

Angular / Zone.js : intercept non-angular XMLHttpRequest-s properly?

问题

我正在开发一个需要包含腾讯验证码的应用程序。与谷歌的验证码不同,腾讯验证码没有很好的文档,这让我感到困惑,不得不对其混淆的代码进行逆向工程分析。

为了实现无缝集成,我需要在它完成XHR调用时获取回调。验证码本身不提供这些回调,所以我需要自己获取它们。

为此,我尝试在Angular启动之前包装XMLHttpRequest对象,但出现了一些错误,如:TypeError: Cannot set property '__zone_symbol__xhrSync' of undefined

阅读了一些教程、书籍章节和文章后,我了解到这种包装已经由Zone.js完成。然而,我仍然不太确定Zone.js是否也包装了非Angular的XHR调用。

如果是的话,如何扩展它以在这些调用完成时获取回调。
如果不是的话,如何在Angular应用程序中为非Angular的XHR调用正确实现XHR拦截器?

以下是我编写的一个XHR拦截器示例,如果没有错误将无法正常工作:

declare global {
  interface Window {
    XHRInterceptor: any;
  }
}

type DataSent = 
  string | Document | Blob | ArrayBufferView | 
  ArrayBuffer | FormData | URLSearchParams | ReadableStream<Uint8Array>;

export class XHRInterceptor {
  constructor() {
    ((original: Function): void => {
      XMLHttpRequest.prototype.send = (data: DataSent): void => {
        console.log('DATA SENT');
        original.call(this, data);
      };
    })(XMLHttpRequest.prototype.send);

    (function(original: Function) {
      // @ts-ignore
      XMLHttpRequest.prototype.open = (
        method: string, url: string, async: boolean,
        username?: string | null, password?: string | null
      ): void => {
        console.log('DATA OPEN');
        original.call(this, method, url, async, username, password);
      };
    })(XMLHttpRequest.prototype.open);
  }
}

要调用它,只需在您的main.ts中添加new XHRInterceptor();

谢谢。

英文:

I am developing an app that needs to include the Tencent Captcha. Contrary to Google's, it is not well documented and drove me to some confusion that made me reverse-engineer its obfuscated code.

For a seamless implementation, I need to get a callback when it finishes it XHR calls. These callbacks are not provided by the captcha. So, I'll have to get them myself.

To do so, I've tried to wrap the XMLHttpRequest object before Angular's boot, but it throws some errors like: TypeError: Cannot set property &#39;__zone_symbol__xhrSync&#39; of undefined.

Reading a few tutorials, book chapters and articles, I understood that this wrapping is already done by Zone.js. However, I am still not very sure whether Zone.js also wraps non-angular HXR calls or not.

If yes, how to extend it to get a callback when these are finished.
If not, how to make a proper implementation of an XHR interceptor for non-angular XHR calls in an Angular App ?

Here is an example of HXRInterceptor I've written, that won't work without error:

declare global {
  interface Window {
    XHRInterceptor: any;
  }
}

type DataSent = 
  string | Document | Blob | ArrayBufferView | 
  ArrayBuffer | FormData | URLSearchParams | ReadableStream&lt;Uint8Array&gt;;

export class XHRInterceptor {
  constructor() {
    ((original: Function): void =&gt; {
      XMLHttpRequest.prototype.send = (data: DataSent): void =&gt; {
        console.log(&#39;DATA SENT&#39;);
        original.call(this, data);
      };
    })(XMLHttpRequest.prototype.send);

    (function(original: Function) {
      // @ts-ignore
      XMLHttpRequest.prototype.open = (
        method: string, url: string, async: boolean,
        username?: string | null, password?: string | null
      ): void =&gt; {
        console.log(&#39;DATA OPEN&#39;);
        original.call(this, method, url, async, username, password);
      };
    })(XMLHttpRequest.prototype.open);
  }
}

To call it, just put new XHRInterceptor(); in your main.ts.

Thank you.

答案1

得分: 1

我能够使用上述代码拦截XHR请求,但是原始的XMLHttpRequest.prototype.open未被执行。因此,在浏览器中没有HTTP请求。

然后,我按照下面的代码并将其放入构造函数中。这样就可以正常工作了。

https://gist.github.com/sergeimuller/a609a9df7d30e2625a177123797471e2

英文:

I am able to intercept the XHR request with the code above, however the original XMLHttpRequest.prototype.open is not executed. Consequently, there is no http request in the browser.

Then I follow the code below and put it into the constructor. And it works.

https://gist.github.com/sergeimuller/a609a9df7d30e2625a177123797471e2

huangapple
  • 本文由 发表于 2020年1月6日 18:04:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/59610082.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定