我如何修改由另一个函数接收XMLHtt prequest responseText的? [英] How can I modify the XMLHttpRequest responsetext received by another function?

查看:697
本文介绍了我如何修改由另一个函数接收XMLHtt prequest responseText的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想修改通过,我不能修改函数接收到的responseText的。该函数创建一个XMLHtt prequest,我可以附加到,但我一直无法包装这个responseText的方式,让我原来的函数接收到之前修改的内容。

I am trying to modify the responseText received by a function that I cannot modify. This function creates a XMLHttpRequest that I can attach to, but I have been unable to "wrap" the responseText in a way that allows me to modify the content before the original function receives it.

下面是完整的原始功能:

Here's the full original function:

function Mj(a, b, c, d, e) {
    function k() {
        4 == (m && 'readyState' in m ? m.readyState : 0) && b && ff(b) (m)
    }
    var m = new XMLHttpRequest;
    'onloadend' in m ? m.addEventListener('loadend', k, !1)  : m.onreadystatechange = k;
    c = ('GET').toUpperCase();
    d = d || '';
    m.open(c, a, !0);
    m.send(d);
    return m
}
function ff(a) {
    return a && window ? function () {
        try {
            return a.apply(this, arguments)
        } catch(b) {
            throw jf(b),
                b;
        }
    } : a
}

我也试图操纵reiceiving函数K();在试图达到我的目标,但由于它不依赖于传递给函数(例如K(a.responseText);)任何数据我没有成功

I have also tried to manipulate the reiceiving function k(); in an attempt to reach my goal, but since it doesn't depend on any data passing to the function (for example k(a.responseText);) I had no success.

有没有什么办法,我能做到这一点?我不想用js库(如jQuery的);

Is there any way that I can achieve this? I do not wish to use js libraries (such as jQuery);

编辑:据我所知,我不能改变.responseText直接,因为它是只读的,但我试图找到一种方法来改变的响应和接收功能之间的内容

I understand that I cannot change .responseText directly since it is read-only, but I am trying to find a way to change the content between the response and receiving function.

EDIT2:增加低于我试图拦截和更改.responseText已经addapted从这里的方法之一:<一个href="http://stackoverflow.com/questions/12575572/monkey-patch-xmlhtt$p$pquest-onreadystatechange">Monkey补丁XMLHTT prequest.onreadystatechange

Added below one of the methods I have tried to intercept and change .responseText which has been addapted from here: Monkey patch XMLHTTPRequest.onreadystatechange

(function (open) {
XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
    if(/results/.test(url)) {
      console.log(this.onreadystatechange);
        this.addEventListener("readystatechange", function () {
            console.log('readystate: ' + this.readyState);
            if(this.responseText !== '') {
                this.responseText = this.responseText.split('&')[0];
            }
        }, false);
    }
    open.call(this, method, url, async, user, pass);
};
})(XMLHttpRequest.prototype.open);

EDIT3:我忘了,包括了功能MJ和FF没有全局可用,它们都包含了一个匿名函数(函数(){功能在这里})()内;

I forgot to include that the functions Mj and ff are not globally available, they are both contained inside an anonymous function (function(){functions are here})();

推荐答案

编辑:请参见下面的第二个code选项(这是测试和工程)。第一个有一定的局限性。

See the second code option below (it is tested and works). The first one has some limitations.

既然你不能修改任何这些功能,看来你有XMLHtt prequest样机后去。这里有一个想法(未经测试,但你可以看到的方向):

Since you can't modify any of those functions, it appears you have to go after the XMLHttpRequest prototype. Here's one idea (untested, but you can see the direction):

(function() {
    var open = XMLHttpRequest.prototype.open;

    XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
        var oldReady;
        if (async) {   
            oldReady = this.onreadystatechange;
            // override onReadyStateChange
            this.onreadystatechange = function() {
                if (this.readyState == 4) {
                    // this.responseText is the ajax result
                    // create a dummay ajax object so we can modify responseText
                    var self = this;
                    var dummy = {};
                    ["statusText", "status", "readyState", "responseType"].forEach(function(item) {
                        dummy[item] = self[item];
                    });
                    dummy.responseText = '{"msg": "Hello"}';
                    return oldReady.call(dummy);
                } else {
                    // call original onreadystatechange handler
                    return oldReady.apply(this, arguments);
                }
            }
        } 
        // call original open method
        return open.apply(this, arguments);
    }

})();

这确实猴子补丁的XMLHtt prequest 的open()方法,然后时调用一个异步请求时,它确实猴子补丁的onreadystatechange的,因为该处理程序应该已经设置。该补丁的功能,然后得到看到这个responseText原onreadystatechange的处理程序被调用之前,所以它可以在不同的值分配给它。

This does a monkey patch for the XMLHttpRequest open() method and then when that is called for an async request, it does a monkey patch for the onReadyStateChange handler since that should already be set. That patched function then gets to see the responseText before the original onReadyStateChange handler is called so it can assign a different value to it.

和,最后因为 .responseText 是现成的只是,这种替代的虚拟XMLHtt presponse对象调用之前的的onreadystatechange 处理程序。这不是在所有情况下工作,但将工作,如果onreadystatechange的处理程序使用 this.responseText 获得响应。

And, finally because .responseText is ready-only, this substitutes a dummy XMLHttpResponse object before calling the onreadystatechange handler. This would not work in all cases, but will work if the onreadystatechange handler uses this.responseText to get the response.

和,下面是重新定义了XMLHtt prequest对象是我们自己的代理对象的尝试。因为这是我们自己的代理对象,我们可以设置的responseText 属性到任何我们想要的。对于所有其他属性除了的onreadystatechange ,该对象只是转发获取,设置或函数调用真正的XMLHtt prequest对象。

And, here's an attempt that redefines the XMLHttpRequest object to be our own proxy object. Because it's our own proxy object, we can set the responseText property to whatever we want. For all other properties except onreadystatechange, this object just forwards the get, set or function call to the real XMLHttpRequest object.

(function() {
    // create XMLHttpRequest proxy object
    var oldXMLHttpRequest = XMLHttpRequest;

    // define constructor for my proxy object
    XMLHttpRequest = function() {
        var actual = new oldXMLHttpRequest();
        var self = this;

        this.onreadystatechange = null;

        // this is the actual handler on the real XMLHttpRequest object
        actual.onreadystatechange = function() {
            if (this.readyState == 4) {
                // actual.responseText is the ajax result

                // add your own code here to read the real ajax result
                // from actual.responseText and then put whatever result you want
                // the caller to see in self.responseText
                // this next line of code is a dummy line to be replaced
                self.responseText = '{"msg": "Hello"}';
            }
            if (self.onreadystatechange) {
                return self.onreadystatechange();
            }
        };

        // add all proxy getters
        ["status", "statusText", "responseType", "response",
         "readyState", "responseXML", "upload"].forEach(function(item) {
            Object.defineProperty(self, item, {
                get: function() {return actual[item];}
            });
        });

        // add all proxy getters/setters
        ["ontimeout, timeout", "withCredentials", "onload", "onerror", "onprogress"].forEach(function(item) {
            Object.defineProperty(self, item, {
                get: function() {return actual[item];},
                set: function(val) {actual[item] = val;}
            });
        });

        // add all pure proxy pass-through methods
        ["addEventListener", "send", "open", "abort", "getAllResponseHeaders",
         "getResponseHeader", "overrideMimeType", "setRequestHeader"].forEach(function(item) {
            Object.defineProperty(self, item, {
                value: function() {return actual[item].apply(actual, arguments);}
            });
        });
    }
})();

工作演示: http://jsfiddle.net/jfriend00/jws6g691/

我想它在IE,Firefox和Chrome浏览器的最新版本,并用一个简单的Ajax请求的工作。

I tried it in the latest versions of IE, Firefox and Chrome and it worked with a simple ajax request.

注:我没有研究过所有的阿贾克斯(如二进制数据,上传,等...),可用于查看该代理不够彻底,使所有这些工作的高级方法(我猜它可能还没有到没有一些进一步的工作,但它正在为基本要求,所以它看起来像概念能)。

Note: I have not looked into all the advanced ways that Ajax (like binary data, uploads, etc...) can be used to see that this proxy is thorough enough to make all those work (I would guess it might not be yet without some further work, but it is working for basic requests so it looks like the concept is capable).

这是失败的其他尝试:

  1. 试图从XMLHtt prequest对象导出,然后用我自己更换的构造,但没有工作,因为真正的XMLHtt prequest功能不会让你把它作为一个函数来初始化我的派生类对象。

  1. Tried to derive from the XMLHttpRequest object and then replace the constructor with my own, but that didn't work because the real XMLHttpRequest function won't let you call it as a function to initialize my derived object.

尝试过重写的onreadystatechange 处理程序,并改变 .responseText ,但该字段为只读所以你不能改变它。

Tried just overriding the onreadystatechange handler and changing .responseText, but that field is read-only so you can't change it.

尝试创建调用的onreadystatechange ,但时发送的对象虚拟对象很多code没有引用,而是具有保存在一个局部变量在一个封闭的实际对象 - 从而击败虚拟对象

Tried creating a dummy object that is sent as the this object when calling onreadystatechange, but a lot of code doesn't reference this, but rather has the actual object saved in a local variable in a closure - thus defeating the dummy object.

这篇关于我如何修改由另一个函数接收XMLHtt prequest responseText的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆