Javascript 停止浏览器“;末日的悸动者”;加载comet/server push XMLHttpRequest时
(这个问题类似于,但它是为了使用XMLHttpRequest而不是Comet的iframe。) 我正在启动一个异步长轮询,如下所示:Javascript 停止浏览器“;末日的悸动者”;加载comet/server push XMLHttpRequest时,javascript,ajax,javascript-events,comet,Javascript,Ajax,Javascript Events,Comet,(这个问题类似于,但它是为了使用XMLHttpRequest而不是Comet的iframe。) 我正在启动一个异步长轮询,如下所示: var xhr = new XMLHttpRequest(); xhr.open('POST', url); xhr.send(); <!-- new HTML 5 tag supporting server-push --> <event-source src="http://myPushService.com" id="service"&g
var xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.send();
<!-- new HTML 5 tag supporting server-push -->
<event-source src="http://myPushService.com" id="service">
<script type="text/javascript">
function handleServiceEvent(event) {
// do stuff
}
// tell browser to fire handleServiceEvent in response to server-push
document.getElementById('service').addEventListener('event name', handleServiceEvent, false);
</script>
如果我在头部的…
中执行此操作,将导致文档永远保持加载状态。(我正在Mac OS X和iPhone上的Safari中进行测试,这是我唯一需要支持的浏览器)
使用DOMContentLoaded
或load
事件将无法工作
使用具有足够大延迟的setTimeout将起作用。有时0不会,有时1000会,有时100会,有时不会。我觉得这样不舒服
我发现有效的唯一方法是两者的结合:
document.addEventListener('DOMContentLoaded', function () {
setTimeout(function () {
var xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.send();
}, 0);
});
我想现在这个问题已经解决了,但我仍然担心将来它会坏掉编辑:这也不能可靠地工作
有人知道更可靠的方法吗?当你说:
…这将导致文档永远保持加载状态
你这到底是什么意思?你的意思是进度条永远不会结束吗?或者实际文档甚至不完全可见?AJAX请求不太可能阻止整个文档的加载,但无论如何
案例1:进度条永远不会结束
这可能是由于AJAX请求从未完成造成的。您是否尝试过在Firebug控制台中查看AJAX请求?它将向您显示发出的请求和服务器的响应。我将从这里开始,只是为了确保服务器正在返回一些内容
案例2:文档元素未完全加载/可见
你可以试着把你的标签放在标签前面
执行此操作时,DOM树在脚本执行之前已完全加载,无需等待“domready”或“onload”启动。另外,请记住,加载的DOM树并不意味着DOM内容(如图像)已完全加载(您需要等待“onload”来确保这一点)
在任何一种情况下,我都会尝试将脚本放在标记之前,这样就有机会构建DOM骨架
旁注:
您是否使用任何类型的调试器查看页面?(Firebug、Webkit检查员)。如果打开控制台并遇到JavaScript错误,Webkit Inspector尤其会停止整个文档的处理。您是否在控制台中看到任何JavaScript错误?如果关闭调试器,页面是否加载?是否可以尝试使用加载事件而不是DOMContentLoaded事件。它应该会有所不同,因为只有在页面完全加载时才会调用它
var xhr;
document.addEventListener('load', function () {
xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.send();
});
这应该行得通。然而,我并不经常使用Comet,所以目前我没有任何方法来测试它
编辑:抱歉,刚才看到Matt已经说过这句话。我不确定,但如果浏览器显示它仍在下载,那么这是完全正确的-Comet编程基本上不是这样吗?服务器仍在发送未缓冲的内容,当这些内容流到javascript块中时,服务器就会执行这些内容,从而允许服务器将事件推送到客户端浏览器 在Ajax早期(例如在IE6上,
XMLHttpRequest
是一个单独的ActiveX对象),我希望浏览器不知道它还在等待
但是在Safari 4、Chrome、FX3.5和所有现代浏览器中,XMLHttpRequest
是内置的,它知道它仍然在等待服务器继续流式传输其内容,就像它使用和
简言之,我希望任何Comet方法都能显示浏览器仍在下载,因为它正在下载。我希望您找到的任何解决方法都能在未来的构建中得到修复,因为Comet本质上是一个让服务器推送模型工作的黑客 然而,他们已经开始在HTML5中构建真正的服务器推送支持 移动Webkit是否支持该标签?如果是这样,你可以尝试一下 然后你会有这样的东西:
var xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.send();
<!-- new HTML 5 tag supporting server-push -->
<event-source src="http://myPushService.com" id="service">
<script type="text/javascript">
function handleServiceEvent(event) {
// do stuff
}
// tell browser to fire handleServiceEvent in response to server-push
document.getElementById('service').addEventListener('event name', handleServiceEvent, false);
</script>
函数handleServiceEvent(事件){
//做事
}
//告诉浏览器触发handleServiceEvent以响应服务器推送
document.getElementById('service').addEventListener('event name',handleServiceEvent,false);
在某些浏览器中,如果没有指定第三个参数,open(…)方法默认情况下会同步发送ajax请求?尝试:
xhr.open('POST', url, true);
显式地使调用异步。为什么不使用一些JS库?jQuery在这里会做得很好。如果你把javascript代码放在结束标记之前,这是一样的吗?Makram,我需要把它保持在最低限度。我认为jQuery在这里没有任何区别。它的ready事件只使用Safari上加载的DOMContentLoaded。大多数comet实现将更新推送到一个隐藏的内部文档或iframe,而不是页面的一部分。我想看看meteor服务器js文件,看看如何实现这一点。我不想这样做。这个问题是关于XHR的。iframe方法的同样问题在我在第一段中链接到的问题中被问到。我的意思是1,进度条/微调器永远不会结束。当然,XHR永远不会结束;我在做Comet,这才是重点,不是这个。Safari默认为async,“我希望任何Comet方法都能显示浏览器仍在下载”。根据该逻辑(如果任何加载=>页面未就绪),如果异步请求作为对用户单击的响应启动,微调器/进度条将重新出现,但不会出现。不幸的是,即使是最新的WebKit每晚都不支持事件源。尽管你的答案现在对我没有帮助,但希望在一年左右的时间里它会是正确的答案,所以我接受了:)干杯——关于进展,我认为重要的区别在于用户点击启动了一个新的过程,而不是页面加载(这就是为什么有时候等待会起作用)。实际上我想看得更清楚些