-1

我想要的非常简单:拦截页面发送的xmlHttpRequests并将它们发送到本地服务器以将其记录在文本文件中。 但很明显,Ajax调用在事件侦听器中不起作用...我找到了几个解决方案,并尝试并尝试并尝试......花了整整一天的时间寻找解决方案。这里的代码:GM_xmlHttpRequest POST在事件侦听器中不起作用

var ajaxQueue = []; 
var processAjaxQueue = function(){ 
    if (ajaxQueue.length > 0) { 
    for (ajax in ajaxQueue) { 
     var obj = ajaxQueue[ajax]; 
     setTimeOut(function(){GM_xmlhttpRequest(obj);},0); 
    } 
    ajaxQueue = []; 
    } 
} 
setInterval(function(){ 
    processAjaxQueue(); 
}, 100); 
function gmAjax(obj){ 
    ajaxQueue.push(obj); 
} 

function envoiData(donnees) 
{ 
       setTimeout(function() {gmAjax({ 
        method: "POST", 
        url: "http://127.0.0.1/log/index.php", 
        data: "prix="+donnees, 
        headers: {"Content-Type": "application/x-www-form-urlencoded"}, 
        onload: function(reponse){alert('Chargé ! '+reponse.responseText);} 
       });}, 0); 
} 

(function(open) { 
    XMLHttpRequest.prototype.open = function(method, url, async, user, pass) { 
     this.addEventListener("readystatechange", function() { 
      console.log(this.readyState); 
      if(this.readyState == 4) 
      { 
       alert(this.responseText); 
       envoiData(this.responseText); 
     } 
     }, false); 
     open.call(this, method, url, async, user, pass); 
    }; 
})(XMLHttpRequest.prototype.open); 

我真的不明白问题所在。 gmAjax的想法来自一个网站,在那个人说,greasemonkey脚本执行并立即停止,因此使用addevent监听器是不可能的。

我在错误控制台中没有错误,并且我的请求在事件侦听器外部工作。

任何帮助赞赏^^

回答

0

最初的想法是正确的。 但是,您需要添加几件事情。

  • 添加@run-at document-start meta,以便在页面发送任何ajax请求之前开始登录。
  • 您需要在实际窗口范围(unsafeWindow)而不是沙箱中使用XMLHttpRequest进行操作。

所以所得到的代码是:

// ==UserScript== 
// @run-at document-start 
// @grant unsafeWindow 
// ==/UserScript== 

var unsafe = unsafeWindow; 

... // keep your ajax queue code here 

var oldOpen = unsafe.XMLHttpRequest.prototype.open; 

unsafe.XMLHttpRequest.prototype.open = function(method, url, async, user, pass) { 
    this.addEventListener("readystatechange", function() { 
     if(this.readyState == 4) 
     { 
      alert(this.responseText); 
      envoiData(this.responseText); 
    } 
    }, false); 
    oldOpen.call(this, method, url, async, user, pass); 
};