是否可以在响应完成之前读取 AJAX 请求?
Posted
技术标签:
【中文标题】是否可以在响应完成之前读取 AJAX 请求?【英文标题】:Is it possible for an AJAX request to be read before the response is complete? 【发布时间】:2011-10-04 16:47:46 【问题描述】:我有一个需要一段时间才能完成的 ajax 请求,但服务器确实会输出一些内容。如果我只是在浏览器中加载请求,我可以看到页面加载缓慢,并且可以随时停止。是否可以在服务器关闭响应之前访问不完整的 ajax 请求?
【问题讨论】:
***.com/questions/2164330/… 我相信原生 XHR 的onreadystatechange
触发的频率比仅在结尾时更频繁。不过,不确定如何使用 jQuery。
不,我不相信 jQuery 会支持它,可能必须找到另一个支持渐进式更新的 AJAX 库或编写自己的实现。
How to load an ajax (jquery) request response progressively without waiting for it to finish?的可能重复
***.com/questions/287286/…
【参考方案1】:
实现这一点的方法是监听 xhr 对象中的 readyState。 当 readyState == 3 时,表示新内容已到,您可以访问它。该技术被称为彗星。
但请注意,不同的浏览器在此处的行为不同,IE 将不允许您访问它See Here,并且 webkit 浏览器 (Chrome/Safari) 在提供数据之前会缓冲 2KB 的数据。不过,在考虑到这一点之后,您就可以倾听变化并采取行动。
不幸的是,jQuery 目前不支持这个开箱即用。您可以按照Bug #8327 中的说明解决此问题,他们基本上会退回到对 readyState 进行轮询以查看它是否发生变化。他们计划将来可能会对此采取一些措施,Bug #9883,但不要屏住呼吸。
所以最后,是的,这是可能的,不,这并不容易。
【讨论】:
谢谢,这个答案解释了很多。 我认为 Comet 确实适用于开放式响应,它允许像套接字一样进行双向通信。本质上允许服务器根据需要推送数据。这里的 OP 实际上只是在谈论一个非常长的响应。然而,同样的技术可能适用。 @jiggy 你说得对,但他想要做的事情需要同样的技巧,主要是从尚未完成的回复中读取,并且了解该术语将有助于他自己的谷歌搜索。跨度> 哦,@Andrew 我不小心把赏金给了错误的人:(我赞成你的一些答案来弥补它......对不起:(【参考方案2】:已经有一些很好的答案,但没有一个是真正 100% 可靠或跨浏览器的。一种更安全的方法可能是将您的响应分成“页面”。每个请求都可以指定与LIMIT
和OFFSET
等效的内容,并且您会不断发出请求,直到收到空响应。这会在客户端和服务器上产生一些额外的开销,但它会更加健壮。
【讨论】:
+1 好主意,简单且保证在所有浏览器中都能正常工作。 噢!我以为我是在将赏金授予安德鲁。好吧,它现在是你的了,因为我无法撤消它。 当。我的代表在一个辉煌的时刻达到了 1337,我觉得自己像一个 SO 大师。现在我看到它是不义的,我会传递它。我有一个未引起兴趣的悬而未决的问题,所以我会把你的 50 分作为赏金放在那个问题上。编辑:显然我需要等到问题足够老了。我会尽快做的。【参考方案3】:取自:https://***.com/questions/287286/jquery-is-req-readystate- 3-possible
将您的 ajax 调用分配给一个变量并将一个事件附加到它的readystatechanged
。
var xhr = $.ajax(...);
xhr._onreadystatechange = xhr.onreadystatechange;
xhr.onreadystatechange = function()
xhr._onreadystatechange();
if (xhr.readyState == 3) alert('Interactive');
;
【讨论】:
这是每个人都应该尝试过的,感谢所有我想发布的帖子:) +1【参考方案4】:我不确定这是否可行,但值得一试:
$.ajax(
statusCode:
206: function() // 206 is partial content
// do work
);
【讨论】:
我不确定,但就我而言,服务器在传输过程中不会发送206 Partial Content
代码,在传输完成后不会发送200 OK
。
在我所知道的任何网络服务器中几乎都不会调用它。只要服务器代码定期刷新内容,检查 3 的 readystate 就更有用了。
是的,我也从未见过 AJAX 请求的 206 响应,但我并不肯定,因为 OP 的情况可能与我遇到的任何情况不同。这就是为什么我认为值得一试。【参考方案5】:
你可以使用长轮询(彗星)代替 ajax 吗?然后,您可以在处理请求时刷新输出缓冲区并读取内容。
http://www.zeitoun.net/articles/comet_and_php/start
【讨论】:
【参考方案6】:Comet 目前是一个不错的解决方法,但在不久的将来它将被 WebSockets 取代。
当然,许多常见的 Web 浏览器尚不支持开箱即用的 WebSocket,但已经有许多 polyfills 模仿了边缘浏览器中的功能,其中许多依赖于Comet(XHR 长轮询)在底层模仿功能。
就我个人而言,我更喜欢 socket.io polyfill,但我对它的体验仅限于与 node.js 一起使用,它可能与您正在使用的东西很好地结合,也可能不适合。
【讨论】:
以上是关于是否可以在响应完成之前读取 AJAX 请求?的主要内容,如果未能解决你的问题,请参考以下文章
ajax 发布请求 - 跨域读取阻塞 (CORB) 阻止跨域响应 CORS
在内容 100% 完成之前从 HttpResponseMessage 读取标头