admin管理员组

文章数量:1346656

These methods that e to mind, what are the pros and cons of each?

Method 1: Augment native instance

var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function() {
    var xhr = new _XMLHttpRequest();

    // augment/wrap/modify here
    var _open = xhr.open;
    xhr.open = function() {
        // custom stuff
        return _open.apply(this, arguments);
    }

    return xhr;
}

Method 2: Sub-"class" native XMLHttpRequest

var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function() {
    // definePropertys here etc
}

XMLHttpRequest.prototype = new _XMLHttpRequest());
// OR
XMLHttpRequest.prototype = Object.create(_XMLHttpRequest);

// custom wrapped methods on prototype here
XMLHttpRequest.prototype.open = function() {
    // custom stuff
    return _XMLHttpRequest.prototype.open.apply(this, arguments);
}

Method 3: Full proxy to native XMLHttpRequest

var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function() {
    this.xhr = new _XMLHttpRequest();
}

// proxy ALL methods/properties
XMLHttpRequest.prototype.open = function() {
    // custom stuff
    return this.xhr.open.apply(this.xhr, arguments);
}

These methods that e to mind, what are the pros and cons of each?

Method 1: Augment native instance

var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function() {
    var xhr = new _XMLHttpRequest();

    // augment/wrap/modify here
    var _open = xhr.open;
    xhr.open = function() {
        // custom stuff
        return _open.apply(this, arguments);
    }

    return xhr;
}

Method 2: Sub-"class" native XMLHttpRequest

var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function() {
    // definePropertys here etc
}

XMLHttpRequest.prototype = new _XMLHttpRequest());
// OR
XMLHttpRequest.prototype = Object.create(_XMLHttpRequest);

// custom wrapped methods on prototype here
XMLHttpRequest.prototype.open = function() {
    // custom stuff
    return _XMLHttpRequest.prototype.open.apply(this, arguments);
}

Method 3: Full proxy to native XMLHttpRequest

var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function() {
    this.xhr = new _XMLHttpRequest();
}

// proxy ALL methods/properties
XMLHttpRequest.prototype.open = function() {
    // custom stuff
    return this.xhr.open.apply(this.xhr, arguments);
}
Share Improve this question edited Feb 1, 2011 at 20:23 tlrobinson asked Jan 26, 2011 at 19:56 tlrobinsontlrobinson 2,8584 gold badges33 silver badges35 bronze badges 6
  • The easiest way would be simply using jQuery (or any other JavaScript framework). – ThiefMaster Commented Jan 26, 2011 at 20:13
  • Your first method seems wrong to me. I fear you'll get in a recursive loop until you get a Stack Overflow. ;) And why do you want this anyway? There are plenty of neater solutions, that don't have to provide function calls to a referenced object. – Marcel Korpel Commented Jan 26, 2011 at 20:55
  • Marcel: you're right, it was a type, I've fixed it. – tlrobinson Commented Feb 1, 2011 at 20:24
  • 3 ThiefMaster: most of my questions are never adequately answered... – tlrobinson Commented Feb 1, 2011 at 20:24
  • using method 3 i get an error TypeError: Object [object Object] has no method 'setRequestHeader' – PPPaul Commented Dec 31, 2014 at 22:25
 |  Show 1 more ment

5 Answers 5

Reset to default 2

Depending on the JS engine, method 1 produces considerable overhead, since xhr.open is redefined whenever XHR is instantiated.

Method 2 makes me think "why would you need the new _XMLHttpRequest in the first place"? There's a minor feeling of undesired side effects, but it appears to work just fine.

Method 3: simple, old-school, but it won't work straight-away. (Think about reading properties)

In general, I'm personally reluctant when it es to overwriting browser objects, so that would be a big con to all three methods. Better use some other variable like ProxyXHR (just my 2 cents)

It may depend on the use case. In my case I wanted to create a plete proxy which seems to be only possible with the third method. The problem is that onreadystatechange needs to be set on the original XHR implementation. I guess there are getter and setter defined that cannot be changed from outside.

Because of this method 1 and 2 will not work. To achieve this I wrote a plete, meaning I didn't find any bugs, proxy to XHR here: A: How can I catch and process the data from the XHR responses using casperjs?. It needs to be done with method 3.

I have tried all 3. I have to intercept calls from within code that I do not manage that already has Boomerang AutoXHR plugin running and intercepting calls. #2 and #3 just resulted in errors but #1 worked perfectly in my strange messed up use-case.

(function () {
  const OriginalXMLHttpRequest = XMLHttpRequest;

  XMLHttpRequest = function () {
    const xhr = new OriginalXMLHttpRequest();
    const xhrProxy = new Proxy(xhr, {
      get(target, prop) {
        if (prop === 'open') {
          return function (...args) {
            target._method = args[0];
            target._requestURL = args[1];
            target._async = args[2];
            return target.open.apply(target, args);
          };
        }

        if (prop === 'send') {
          return function (body) {
            target._body = body;
            if (target._requestURL.includes("you-url-requirements")) {
              // Debugging logs
              console.log("Intercepted Request", {
                method: target._method,
                url: target._requestURL,
                body: target._body,
              });
            }

            // Attach event listener before sendin
            return target.send.call(target, body);
          };
        }

        // Intercept accessing responseText, status, and statusText
        if (['responseText', 'status', 'load'].includes(prop)) {
          if (target._requestURL && target._requestURL.includes("search?tbm")) {
            console.log("

本文标签: javascriptHow can I create a XMLHttpRequest wrapperproxyStack Overflow