我的AJAX,Greasemonkey脚本中的间歇行为

时间:2011-10-26 04:24:57

标签: javascript xmlhttprequest greasemonkey

我有一个小Greasemonkey脚本,不包含任何随机部分,但其结果随每次页面重新加载而变化。

我是一个菜鸟,我可能做错了什么,但我不知道是什么。我希望你能帮助我。

代码太大而且编写得太差而无法在此处复制,因此我将总结一下我的情况:

  • 我有一个包含href=javascript:void(0)onclick=f(link_id)
  • 的链接列表
  • f(x)向服务器发出XML HTTP请求,并返回链接地址。
  • 我的脚本用于预先计算f(x)并在页面加载时更改href值。

我有一个等待页面加载的函数wait(),然后是一个函数findLinks(),它获取要更改的节点(使用xpath)。
然后是一个将xhr发送到服务器的函数sendRequest()。最后,handleRequest()异步(r.onreadystatechange)检索响应,并设置先前找到的节点。

你认为这个想法有什么问题吗?

使用网络分析器,我可以看到请求总是正常发送,响应也是。

有时href值会发生变化,但有时某些链接不会改变,而且仍为javascript:void(0)

我真的不明白为什么它的工作只有一半......

function getUrlParameterFromString(urlString, name) {
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regexS = "[\\?&]" + name + "=([^&#]*)";
    var regex = new RegExp(regexS);
    var results = regex.exec(urlString);
    if (results == null) {
        return "";
    } else {
        return results[1];
    }
}

function getUrlParameter(name) {
    return getUrlParameterFromString(window.location.href, name);
}

function wait() {

    var findPattern = "//a";
    var resultLinks = document.evaluate(findPattern, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

    if (resultLinks == null || resultLinks.snapshotLength == 0) {
        return setTimeout(_wait, 100);

    } else {
        for (var i = 0, len = resultLinks.snapshotLength; i < len; i++) {
            var node = resultLinks.snapshotItem(i);
            var s = node.getAttribute('onclick');
            var linkId = s.substring(2, s.length - 1); // f(x)->x
            sendRequest(linkId, node);
        }
    }
}

function sendRequest(linkId, nodeToModify) {

    window.XMLHttpRequest ? r = new XMLHttpRequest : window.ActiveXObject && (r = new ActiveXObject("Microsoft.XMLHTTP"));

    if (r) {
        r.open("POST", "some_url", !0);
        r.onreadystatechange = function () {
            handleRequest(nodeToModify, linkId, r);
        }
        r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        r.send(linkId);
    }

}

function handleRequest(nodeToModify, num, r) {
 if (r.readyState == 4) {
     if (r.status == 200) {
         console.log('handleRequest() used');
         var a = r.responseText;
         if (a == null || a.length < 10) {
             sendRequest(num, nodeToModify);
         } else {
             var url = unescape((getUrlParameterFromString(a, "url")).replace(/\+/g, " "));
             nodeToModify.setAttribute('href', url);
             nodeToModify.setAttribute('onclick', "");
         }
     } else {
         alert("An error occurred: " + r.statusText)
     }
 }

}

wait();

1 个答案:

答案 0 :(得分:0)

看起来该脚本将完全改变1个链接。查找“closures”; 此循环:

for (var i = 0, len = resultLinks.snapshotLength; i < len; i++) {
    var node = resultLinks.snapshotItem(i);
    var s = node.getAttribute('onclick');
    var linkId = s.substring(2, s.length - 1); // f(x)->x
    sendRequest(linkId, node);
}

需要关闭,以便sendRequest()获取正确的值。否则,只会修改最后一个链接。


尝试:

for (var i = 0, len = resultLinks.snapshotLength; i < len; i++) {
    var node = resultLinks.snapshotItem(i);
    var s = node.getAttribute('onclick');
    var linkId = s.substring(2, s.length - 1); // f(x)->x

    //-- Create a closure so that sendRequest gets the correct values.
    ( function (linkId, node) {
            sendRequest (linkId, node);
        }
    )(linkId, node);
}