preface

Some time ago, when the project was adapting WKWebview, it came into contact with the Ajax-hook scheme used by the public capability group, so it became very interested in how to implement it. When I searched online, I found the author @wendux’s Ajax-hook principle to analyze this article. At that time while looking at the brain side think: “God, this SAO operation how to feel Proxy can also come to a wave!” . When I see a brother @Yinxueqianzai in the comment section of this article has also made the same question, I will smile and do it immediately. It will be a complete operation if I open VSCode.

About ES6 Proxy

It’s not new either, but since it doesn’t support IE and Safari 10 just started supporting it, it’s been used with caution. I’ve been looking for some best practices, and this should be a practice. For those who are not familiar with it, take a look at Proxy on MDN and Proxy in ECMAScript 6 introduction. This implementation uses its get, set and construct methods.

About the XMLHttpRequest

XMLHttpRequest is no stranger to us, and although it is becoming increasingly unnecessary to operate directly with it thanks to excellent request libraries such as AXIos, familiarity with it should be beyond the surface, as some browser adaptations and front-end monitoring and burying points still require dealing with it. Here we need to be clear about a few things:

  • likeresponse,responseText,timeoutThese are the kinds of properties, let’s just call themCommon properties
  • The corresponding imageonreadystatechange,onprogress,onloadProperties of this kind are calledEvent attributes
  • Of course, there are some moreopen,send,abortThis class is calledmethods
  • I’m focusing on one place, and there are a lot of properties that are notwritableAs shown in the figure below

So we need to do something special when we intercept these attributes.

The principle of analytic

This section suggests looking at the API first, or opening the API and keeping it on the side for better results.

As with Ajax-hook, the whole is in proxy mode. Here is the schematic diagram of the previous whole:

First of all, whatever request scheme the project (browser side) uses, as long as it ends up using the XMLHttpRequest in the Host Object, it needs to use

var xhr = new XMLHttpRequest()
Copy the code

Instantiate, so we can intercept the XMLHttpRequest object’s new operation and implement the code using the Proxy construct method. In intercept operations, we do two simple things:

  • instantiationXMLHttpRequest
  • withProxyContinue to interceptXMLHttpRequestAn instance of the

Then we go further in the second step above, intercepting the instance with get and set. Let’s focus on what those two methods do.

  • get(target, p, receiver)

    • Get intercepts common attributes as follows

      As mentioned above, some attributes are not writable, so we will cache these attributes into attributes with the same name with prefix _ in the subsequent set operation. Therefore, we need to check whether these attributes with prefix _ exist and then read them. The writable property is read through the getter function.

    • Intercept the method as follows

      When intercepting a method, it checks whether the user provides an intercepting function, executes it and records the result as result, then determines the result type, and terminates the method if true. (I’ve added a function to pass result as a new argument if it returns another truthy value like Object or function.)

  • set(target, p, value, receiver)

    • Intercept the event attribute as follows

      Very simple, also is whether the user provides the interception function, if so, execute first.

    • Set intercepts common attributes as follows

      This is a special operation on a property that is not writable.

Finally, you simply assign the Proxy object instance generated by the above code to the host object XMLHttpRequest and you’re done. That’s pretty much all the code, so here’s a summary:

Ajax-proxy uses a proxy to intercept the new operation of the host object XMLHttpRequest, and then creates a proxy instance to intercept the GET and set of the XMLHttpRequest instance. Finally, the generated Proxy object instance is assigned to the host object XMLHttpRequest, Done!

The last

Space is limited, some details are not clear or say wrong place please point out, more usage and code please stamp →

Making: github.com/LazyDuke/aj…

Repo also has test cases for intercepting XMLHttpRequest, JQuery’s Ajax module, and Axios. Click Star if you’re interested

This article is allowed to be reproduced free of charge, but please indicate the original author and the link to the original text.