在加载comet / server push XMLHttpRequest时停止浏览器“thomber of doom”

时间:2009-11-14 20:52:13

标签: javascript ajax javascript-events comet

(这个问题类似于this one,但它是为Comet使用XMLHttpRequest而不是iframe。)

我正在开始像这样的异步长调查:

var xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.send();

如果我在头部<script>...</script>内执行此操作,则会导致文档永远保持加载状态。 (我在Mac OS X和iPhone上的Safari中测试它,它是我需要支持的唯一浏览器。)

使用DOMContentLoadedload事件将无效。

使用带有足够延迟的setTimeout将起作用。 0将不会,1000将,100将有时,而不是其他时间。我对此感到不舒服。

我发现作品的唯一方法是两者结合:

document.addEventListener('DOMContentLoaded', function () {
    setTimeout(function () {
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url);
        xhr.send();
    }, 0);
});

我想现在这解决了这个问题,但是我仍然担心它将来会破裂。 //编辑:这也无法可靠地运作。

有谁知道更可靠的方式?

4 个答案:

答案 0 :(得分:2)

我不确定,但似乎如果浏览器显示它仍在下载那么这完全正确 - 那么Comet编程基本上不是吗?服务器仍在发送无缓冲的内容,当它在javascript块中流动时,它会被执行,允许服务器将事件推送到客户端浏览器。

在早期的Ajax中(例如在IE6上XMLHttpRequest是一个单独的ActiveX对象)我希望浏览器不知道它还在等待。

但是在Safari 4,Chrome,FX3.5和内置XMLHttpRequest的所有现代浏览器中 - 它知道它仍然在等待服务器仍然流式传输其内容,就像它使用和{ {1}}

简而言之 - 我希望任何Comet方法都能显示浏览器仍在下载,因为它是。我希望你发现的任何解决方法都能在未来的构建中得到修复,因为Comet实际上是一个让服务器推送模型工作的黑客。

然而,他们已经开始在HTML 5中构建真正的服务器推送支持。

移动Webkit是否支持HTML 5 draft event-source标记?如果是这样,你可能会尝试这样做。

然后你会有这样的事情:

<IFrame>

答案 1 :(得分:1)

当你说:

  

...它会使文档永远保持加载状态。

你到底是什么意思?你是说进度条永远不会结束?或者实际文件是否完全不可见? AJAX请求不太可能阻止整个文档加载,但无论如何......

案例1:进度条永远不会完成

这很可能是因为AJAX请求永远不会完成。您是否尝试在Firebug控制台中查看AJAX请求?它将向您显示请求和服务器的响应。我会从这里开始,以确保服务器正在发送某些东西

案例2:文档元素未完全加载/可见

您可以尝试输入&lt; script&gt;标签就在&lt; / body&gt;之前标签

执行此操作时,DOM 在脚本执行之前已完全加载,您无需等待“domready”或“onload”触发。另外,请记住,正在加载的DOM 并不意味着DOM 内容(例如图像)已经完全加载(您需要等待'onload'为当然可以确定)

在任何一种情况下,我都会尝试将脚本放在&lt; / body&gt;之前。标签,所以DOM骨架有机会建立。

旁注:

您是否使用任何类型的调试器查看您的页面? (Firebug,Webkit Inspector)。特别是Webkit Inspector实际上会在控制台打开并且遇到JavaScript错误时停止处理整个文档。你在控制台中看到任何JavaScript错误吗?如果关闭调试器,页面会加载吗?

答案 2 :(得分:0)

您是否可以尝试使用load事件而不是DOMContentLoaded事件。它应该有所作为,因为它只在页面完全加载时调用。

var xhr;
document.addEventListener('load', function () {
    xhr = new XMLHttpRequest();
    xhr.open('POST', url);
    xhr.send();
});

这应该有效。但是,我不经常与Comet合作,所以我现在没办法测试它。

编辑:对不起,刚看到马特已经说过了。

答案 3 :(得分:0)

在某些浏览器中,如果没有指定第三个参数,open(...)方法默认同步发送ajax请求?尝试:

xhr.open('POST', url, true);

显式地使调用异步。