2012-06-16 11 views
0

的userscript問題:http://userscripts.org/scripts/show/130532XMLHttpRequest的啓動多次,沒有啓動的onreadystatechange函數

它已作出已經更新到HTML5網站後,我不得不更新腳本。但是,現在它有一個非常大的問題。當我啓動包含XMLHttpRequest的腳本的主函數時,它只是簡單地用這些請求來分發控制檯,直到瀏覽器崩潰。

現在,我查看了StackOverflow和Google的任何幫助我的東西,但沒有任何東西。

如果您繼續嘗試該腳本,請小心,因爲它會使瀏覽器崩潰。或者至少,它爲我在FF 11.00

代碼:

// ==UserScript== 
// @name   Where my thread at 
// @include  *//boards.4chan.org/*/res/* 
// ==/UserScript== 

(function() { 
    "use strict"; 
    var board = document.location.href.match(/https?:\/\/boards\.4chan\.org\/[\w]+/i), threadNo = location.pathname.match(/\/res\/([\d]+)/i), main = document.getElementsByName("delform")[0], is404 = 0, ttt = null, b, c, num, timer, html, i, l, no, found, xhr1, xhr2, cstatus, ui, pg; 

    function lookup(resp) { 
     html = resp.match(/<div class="postContainer opContainer".*?<\/div>[^<]*?<\/div>/gi); 
     if (html) { 
      l = html.length; 
      for (i = 0; i < l; i += i) { 
       no = html[i].match(/<a href="res\/([\d]+)"/i)[1]; 
       if (threadNo[1] === no) { 
        document.getElementById('page').innerHTML = pg; 
        cstatus.innerHTML = "Status:&nbsp;Done"; 
        found = 1; 
        break; 
       } 
      } 
     } 
    } 

    function doIndex(pg) { 
     b = document.getElementById('shouldi'); 
     if (!is404 && b.checked === true) { 
      cstatus.innerHTML = "Status:&nbsp;Searching"; 
      c = document.getElementById('timerbox'); 
      num = parseInt(c.value, 10); 
      if (num > 600) { timer = 600; } 
      if (num < 30) { timer = 30; } 
      if (isNaN(num)) { 
       timer = 60; 
       alert("Value entered is not a valid number! Defaulting to 60"); 
       c.value = "60"; 
      } 
      if (!timer) { timer = num; } 
      xhr1 = new XMLHttpRequest(); 
      xhr1.open("GET", board[0] + (0 === pg ? "" : "/" + pg), true); 
      xhr1.setRequestHeader("Cache-Control", "no-cache"); 
      xhr1.onreadystatechange = function() { 
       if (xhr1.readyState === 4) { 
        if (xhr1.status === 200) { 
         lookup(xhr1.responseText); 
        } 
       } 
       if (found) { 
        ttt = setTimeout(function() { 
         doIndex(0); 
        }, timer * 1000); 
       } else { 
        if (pg < 15) { 
         doIndex(pg + 1); 
        } else { 
         cstatus.innerHTML = "Status:&nbsp;Really 404?"; 
         xhr2 = new XMLHttpRequest(); 
         xhr2.open("GET", board[0] + threadNo[0], true); 
         xhr2.setRequestHeader("Cache-Control", "no-cache"); 
         xhr2.onreadystatechange = function() { 
          if (xhr2.readyState === 4) { 
           if (xhr2.status === 404) { 
            cstatus.parentNode.removeChild(cstatus); 
            document.getElementById('page').innerHTML = "404'd"; 
            is404 = 1; 
           } else { 
            cstatus.innerHTML = "Status:&nbsp;Still alive"; 
            setTimeout(function() { 
             doIndex(0); 
            }, 1000); 
           } 
          } 
         }; 
         xhr2.send(null); 
        } 
       } 
      }; 
      xhr1.send(null); 
     } 
    } 

    ui = document.createElement('center'); 
    ui.innerHTML = '<table border="0" style="width: 100%"><tbody><tr><td style="width: 33%;text-align: right;">Timer(600-30s):&nbsp;<input type="text" value="30" maxlength="3" size="3" id="timerbox">&nbsp;&nbsp;</td><td style="width: 33%">&nbsp;<center><font size="20" color="red" id="page">&nbsp;</font></center>&nbsp;</td><td style="width: 33%;text-align:left;">&nbsp;&nbsp;<span id="checkcheck"><label for="shouldi">Checking</label><input type="checkbox" id="shouldi" /></span>&nbsp;&nbsp;<span id="checkstatus">Status:&nbsp;</span></td></tr></tbody></table>'; 
    main.parentNode.insertBefore(ui, main); 
    cstatus = document.getElementById('checkstatus'); 
    cstatus.innerHTML = "Status:&nbsp;Ready"; 
    document.getElementById('checkcheck').addEventListener("click", function() { 
     if (ttt !== null) { 
      clearTimeout(ttt); 
      ttt = null; 
     } 
     setTimeout(function() { 
      doIndex(0); 
     }, 500); 
    }, false); 
}()); 
+0

@BrockAdams OP是該腳本的作者(參見Gravatar)。代碼必須包含在問題中,因爲可以刪除用戶腳本,這個問題對於未來的訪問者來說沒有用處。 –

+0

@RobW,好眼睛(或者OP操作可憐KittyAwesome的帳戶;))。你是對的,代碼應該包括在內,但這個問題似乎不太可能幫助除OP之外的任何其他問題。 –

+0

我不打算刪除這個用戶有史以來,所以不要擔心。另外,userscripts.org有版本歷史記錄。 – user1263513

回答

4

您使用的幾個變量不宣這些本地

var ..., found, xhr1, xhr2, cstatus, ui, pg; 
... 
function doIndex(pg) { 
    ... 
     xhr1 = new XMLHttpRequest(); 
    // ^^^^ No var !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
     ... 
     xhr1.onreadystatechange = function() { 
      if (xhr1.readyState === 4) { ... } 
      if (found) { 
       ... 
      } else { 
       if (pg < 15) { 
        doIndex(pg + 1); // <-- !!!!!!!!!!!!!!!!!! 
       } else { ... 
        xhr2 = new XMLHttpRequest(); 
        ... 
        xhr2.onreadystatechange = function() { ... }; 
        xhr2.send(null); 
       } 
      } 
     }; 
     xhr1.send(null); 
    } 
} ... 
doIndex(0); // Initiate the doom 

首先,您指定將新的XHR實例添加到非本地xhr1變量。
然後,添加readystatechange事件處理程序,在出現以下情況:

  1. 最初,readyState是不是四個,所以found是假的。由於pg從0開始,因此調用doIndex(pg + 1)。現在,xhr1被新的XHR實例覆蓋。
  2. 這樣下去,直到達到pg 15.然後,pg < 15是假的,並且恐怖開始:
    • xhr1.onreadystatechange火災多個時間請求期間。 pg < 15是假的,所以else塊進行評估,從中推出多款新XHR(xhr2)請求......
    • 以前所有的readystatechange事件仍在解僱,因爲請求還沒說完呢。在每個事件處理程序中,您正在比較xhr1.readyState的值,該值指的是最後的的創建xhr1請求的狀態。
      因此,您一遍又一遍地調用doIndex(pg+1),一旦pg達到15,就會創建新的XHR(xhr2)實例。

要解決該問題,在函數聲明變量,幷包裹在if (xhr1.readyState == 4)整個onreadystatechange塊(或使用onload代替onreadystatechange)。

function dIndex(pg) { 
    var xhr1, xhr2; 
    ... 
    xhr1.onreadystatechange = function() { 
     if (xhr1.readyState === 4) { 
      /* ... */ 
     } 
    }; 
    ... 
+0

+1耐心(以及一個合理的答案)。 –

+0

那麼,我已經玩過你說過的話,但不知怎的,他們都沒有按預期工作。我終於放棄了,回到了早期版本並更新了它。它也不能像現在這樣工作,因爲當我勾選複選框時,它會在第一個紙板頁面上觸發兩次XMLHttpRequest。如果您有任何想法,請隨時在腳本的討論頁面上撰寫。 – user1263513