【问题标题】:How to prevent XMLHttpRequest from buffering the entire response如何防止 XMLHttpRequest 缓冲整个响应
【发布时间】:2013-08-30 15:10:07
【问题描述】:

我正在尝试对我的服务器上的流式端点使用 ajax 调用。连接应该能够永远接受来自服务器的推送数据,但 XMLHttpRequest 似乎缓冲了整个响应。我只希望浏览器客户端接收每个数据块一次,然后继续下一个。

有没有办法防止这种行为?

更新:似乎 Firefox 能够通过将 XMLHttpRequest.responseType 设置为“moz-chunked-text”或“moz-chunked-arraybuffer”来支持这一点。不过其他浏览器不支持。无论如何,这可能不是最好的方法。

WebKit equivalent to Firefox's "moz-chunked-arraybuffer" xhr responseType

【问题讨论】:

  • Ajax 并不真正意味着永远开放和多条消息传递。可以这样做,但您需要自行确定响应的哪一部分是新的,或者您需要定期回收连接 (long polling)。适合这个角色的是WebSockets
  • 流式 http 端点(没有 websocket 开关)是否因此不适合基于浏览器的客户端使用?
  • 也就是说,如果服务器数据流的频率很高,那么长轮询就会丢失数据。

标签: javascript ajax streaming


【解决方案1】:

看看这个http://en.wikipedia.org/wiki/Comet_(programming)

我有一个使用 Ajax 轮询服务器的网页,我在其中实现了 Comet 服务器。浏览器向服务器发送请求,并且仅在服务器上触发事件时(在我的情况下,当文件完成生成时)接收响应。如果服务器在超时(30 秒)后没有响应,它会发送一个空响应。每次客户端收到 Ajax 响应时,它都会立即发送一个新请求。

优点是你不需要经常轮询服务器,只要服务器上有事件就会通知你的客户端。

【讨论】:

    【解决方案2】:

    查看此维基 http://en.wikipedia.org/wiki/Push_technology

    我相信您想到的是长轮询。服务器将其输出设置为分块的位置(有关 php 示例,请参见 How to make PHP generate Chunked response

    一旦你有一个服务器发送一个分块的响应,你可以使用类似https://github.com/flowersinthesand/portal 的东西来持续读取流。

    如果您无法更改服务器传输编码,或者您必须坚持使用 ajax,则另一种方法是让您的客户端轮询服务器以进行更改。类似的东西(使用 jQuery 来缩短它)

    setInterval(function(){
       // last_updated lets you compare what's changed since the last call so you can stream updates. Or you could have the server respond with a certain amount of bytes, and then have this param remember where they are in the stream and send the next X bytes
       $.get("/my/endpoint?last_updated=" + (new Date().getTime()), function(d){
          console.log("Got response");
       });
    }, 5000); // Refresh every 5 seconds
    

    就我个人而言,我很幸运使用Socket.io 它是基于node.js 的,但它会处理如何,因此每个客户端都会获得尽可能好的性能。 (在内部,它尝试使用 websockets 并退回到 flash 套接字,然后轮询,以便您在新的浏览器上获得惊人的速度,同时仍然支持所有人)

    【讨论】:

    • 在我的情况下,数据以相当高的频率出现(块之间
    • 那么您正在寻找 websocket、flash socket 或分块响应。使用诸如 socket.io 之类的东西(如果可能,它使用 websockets)也可以获得事件驱动的响应。根据您的服务器设置(例如,如果您使用的是 apache + php),它可能未针对发送分块响应进行优化;而 socket.io 的设计目的是有一个开放的套接字来一次发送小块。
    猜你喜欢
    • 1970-01-01
    • 2012-04-13
    • 2015-07-31
    • 2014-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2023-03-03
    相关资源
    最近更新 更多