XMLHttpRequest 在不启动 onreadystatechange 函数的情况下启动多次
XMLHttpRequest launches multiple times without initiating the onreadystatechange function
有问题的用户脚本:http://userscripts.org/scripts/show/130532
在为它制作的网站更新到 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: Done";
found = 1;
break;
}
}
}
}
function doIndex(pg) {
b = document.getElementById('shouldi');
if (!is404 && b.checked === true) {
cstatus.innerHTML = "Status: 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: 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: 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): <input type="text" value="30" maxlength="3" size="3" id="timerbox"> </td><td style="width: 33%"> <center><font size="20" color="red" id="page"> </font></center> </td><td style="width: 33%;text-align:left;"> <span id="checkcheck"><label for="shouldi">Checking</label><input type="checkbox" id="shouldi" /></span> <span id="checkstatus">Status: </span></td></tr></tbody></table>';
main.parentNode.insertBefore(ui, main);
cstatus = document.getElementById('checkstatus');
cstatus.innerHTML = "Status: Ready";
document.getElementById('checkcheck').addEventListener("click", function () {
if (ttt !== null) {
clearTimeout(ttt);
ttt = null;
}
setTimeout(function () {
doIndex(0);
}, 500);
}, false);
}());
你正在使用多个变量,而没有在本地声明这些变量:
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
事件处理程序,其中将发生以下情况:
- 最初,
readyState
不是四个,所以found
是假的。由于pg
从 0 开始,因此调用doIndex(pg + 1)
。现在,xhr1
被新的 XHR 实例覆盖。 - 这种情况一直持续到
pg
达到15岁。然后,pg < 15
是假的,恐怖开始了:-
xhr1.onreadystatechange
在请求期间多次触发。pg < 15
是假的,所以else
块被评估,你在其中启动几个新的XHR(xhr2
)请求... - 所有以前的 readystatechange 事件仍会触发,因为请求尚未完成。在每个事件处理程序中,您都在比较
xhr1.readyState
的值,该值是指上次创建的xhr1
请求的状态。
因此,您一遍又一遍地调用doIndex(pg+1)
,一旦pg
达到 15,就会创建新的 XHR(xhr2
)实例。
-
要解决此问题,请在函数中声明变量,并将整个onreadystatechange
块包装在if (xhr1.readyState == 4)
中(或使用onload
而不是onreadystatechange
)。
function dIndex(pg) {
var xhr1, xhr2;
...
xhr1.onreadystatechange = function() {
if (xhr1.readyState === 4) {
/* ... */
}
};
...
这基于答案有所帮助:
let signupRequest = new XMLHttpRequest();
let url = "signup/" + inputMobile.value;
signupRequest.open("GET", url, true);
signupRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
signupRequest.send();
signupRequest.onreadystatechange = function () {
if (signupRequest.readyState === 4) {
hideLoading();
if (signupRequest.status === 200) {
console.log("OK: " + status + " --- " + signupRequest.response);
} else {
console.log("NOK: " + status + " --- " + signupRequest.response);
}
}
};
相关文章:
- jQuery悬停在没有鼠标悬停的情况下启动
- Apache Cordova:在不启动浏览器应用程序的情况下运行Cordova运行浏览器
- 默认情况下在代码镜像中启动全屏
- Ajax-函数在没有调用或单击的情况下启动
- 是否可以在所有值都为0的情况下启动D3JS饼图
- 返回按钮回调函数在特定情况下失败或未启动
- 只有在前一个功能成功完成的情况下,我才能正确地启动此功能
- 如何在没有用户确认的情况下在iPhone的浏览器中启动音频
- 在不重新加载文件的情况下重新启动 gif 动画
- XMLHttpRequest 在不启动 onreadystatechange 函数的情况下启动多次
- 如何在不重新启动 Web 应用程序的情况下以编程方式使 JavaScript 和 CSS 包失效或刷新
- 如何在没有window.open的情况下从Javascript启动PHP文件
- 在不更改 html 内容的情况下“启动”iframe
- 我的代码在没有警报()的情况下无法正常工作;启动函数
- 即使在自动播放=“假”预加载=“无”之后,视频也会在不单击播放按钮的情况下启动
- 在不执行浏览器操作的情况下启动chrome扩展
- 默认情况下,在启动时执行条件AND中的一行
- 在没有回调的情况下在ajax加载后启动jQuery脚本
- 为什么我的for循环在某些情况下没有启动?
- HTML和JSP—如何在不移动到另一个页面的情况下启动表单上的操作