我在玩这个XmlHttpRequest
东西。在一些教程和书籍中,它是onload
在请求完成时调用的函数。在我的小实验中,这个函数永远不会被调用。这是我的代码:
window.onload = function() {
var url = "http://www.google.com";
var request = new XMLHttpRequest();
request.onload = function() {
var state = this.readyState;
var responseCode = request.status;
console.log("request.onload called. readyState: " + state + "; status: " + responseCode);
if (state == this.DONE && responseCode == 200) {
var responseData = this.responseText;
alert("Success: " + responseData.length + " chars received.");
}
};
request.error = function(e) {
console.log("request.error called. Error: " + e);
};
request.onreadystatechange = function(){
console.log("request.onreadystatechange called. readyState: " + this.readyState);
};
request.open("GET", url);
request.send(null);
};
我正在上一个 Firefox 版本(今天刚刚更新)上对此进行测试。永远不会打印日志行onload
,并且永远不会命中我在第一行中设置的断点。但是,该onreadystatechange
函数被调用了两次,实际上是发出了http请求。这是萤火虫的控制台显示的:
request.onreadystatechange called. readyState: 1
GET http://www.google.com/ 302 Found 174ms
request.onreadystatechange called. readyState: 4
NS_ERROR_FAILURE: Failure
request.send(null);
行中有错误send
。我尝试将其更改为request.send()
具有相同的结果。
起初我以为这可能是浏览器试图阻止 XSS,所以我将我的 html 驱动程序页面移动到我的开发机器中的一个 Tomcat 实例,但结果是一样的。
是否保证调用此函数?正如我上面所说的,在大多数教程中很常见,但另一方面,在W3C 规范页面中,hello world 片段使用onreadystatechange
了:
function processData(data) {
// taking care of data
}
function handler() {
if(this.readyState == this.DONE) {
if(this.status == 200 &&
this.responseXML != null &&
this.responseXML.getElementById('test').textContent) {
// success!
processData(this.responseXML.getElementById('test').textContent);
return;
}
// something went wrong
processData(null);
}
}
var client = new XMLHttpRequest();
client.onreadystatechange = handler;
client.open("GET", "unicorn.xml");
client.send();
它检查readyState == this.DONE
. DONE
值为 4,这是我在日志中看到的。因此,如果这是与 XSS 相关的问题,并且浏览器阻止我连接到不同的域,那么为什么会建立实际连接并收到 DONE 状态???
PS:是的,我知道有强大的库可以轻松做到这一点,但我仍然是 JavaScript 菜鸟,所以我想先了解底层。
更新:
我已将 URL 更改为我的域 (localhost) 中的一个,错误消失了,但onload
仍未调用该函数。在 IE8 中测试并不起作用。在 Chrome 中测试并有效。怎么样?
更新 2:
在 Firefox 中再次测试,现在它可以工作了。可能旧页面仍在缓存中,所以我无法立即注意到它。在 IE8 中仍然失败,我将尝试在较新的版本中对其进行测试。