我正在玩这个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请求。这是 firebug 的控制台显示的内容:
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 规范页面 http://www.w3.org/TR/XMLHttpRequest/,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 菜鸟,所以我想首先了解底层。
UPDATE:
我已将 URL 更改为我的域 (localhost) 内的 URL,错误消失了,但onload
函数仍未被调用。在IE8下测试,无效。在 Chrome 中测试并有效。怎么样?
更新2:
在 Firefox 中再次测试,现在可以工作了。可能旧页面仍然被缓存,所以这就是为什么我无法立即注意到它。在 IE8 中仍然失败,我会尝试在较新的版本中测试它。