最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

http - Consuming chunked data asyncrhonously in javascript - Stack Overflow

programmeradmin3浏览0评论

I have a (GET) endpoint that sends data in chunks (Transfer-Encoding: chunked). The data is JSON encoded and sent line by line.

Is there a way to consume the data sent by this endpoint in an asynchronous manner in JavaScript (or using some JavaScript library)?

To be clear, I know how to perform an asynchronous GET, but I would like to have the GET request not waiting for the whole data to be transfered, but instead read the data line by line as it arrives. For instance, when doing:

curl  http://localhost:8081/numbers

The lines below are shown one by one as they bee available (the example server I made is waiting a second between sending a line and the second).

{"age":1,"name":"John"}
{"age":2,"name":"John"}
{"age":3,"name":"John"}
{"age":4,"name":"John"}

I would like to reproduce the same behavior curl exhibits, but in the browser. I don't want is leave the user wait till all the data bees available in order to show anything.

I have a (GET) endpoint that sends data in chunks (Transfer-Encoding: chunked). The data is JSON encoded and sent line by line.

Is there a way to consume the data sent by this endpoint in an asynchronous manner in JavaScript (or using some JavaScript library)?

To be clear, I know how to perform an asynchronous GET, but I would like to have the GET request not waiting for the whole data to be transfered, but instead read the data line by line as it arrives. For instance, when doing:

curl  http://localhost:8081/numbers

The lines below are shown one by one as they bee available (the example server I made is waiting a second between sending a line and the second).

{"age":1,"name":"John"}
{"age":2,"name":"John"}
{"age":3,"name":"John"}
{"age":4,"name":"John"}

I would like to reproduce the same behavior curl exhibits, but in the browser. I don't want is leave the user wait till all the data bees available in order to show anything.

Share Improve this question edited Mar 10, 2018 at 8:36 Damian Nadales asked Mar 10, 2018 at 8:22 Damian NadalesDamian Nadales 5,0371 gold badge22 silver badges40 bronze badges 7
  • 1 The future answer would likely be developer.mozilla/en-US/docs/Web/API/Streams_API – Dan D. Commented Mar 10, 2018 at 8:39
  • Thanks! That's why I cannot find an answer to this problem anywhere. – Damian Nadales Commented Mar 10, 2018 at 9:00
  • 1 Well Streams_API doesn't look like ing to Firefox anytime soon but ReadableStream is already available with Fetch API. You might find this article on how to handle streams with Fetch API interesting. – Redu Commented Mar 10, 2018 at 14:18
  • Damn! I wish I had seen your answer before re-implementing the end-point to use server sent events :) I'm gonna give ReadableStream a try. – Damian Nadales Commented Mar 10, 2018 at 14:29
  • Right, you may save some workload and a websockets library dependency at the server side. – Redu Commented Mar 10, 2018 at 14:39
 |  Show 2 more ments

1 Answer 1

Reset to default 9

Thanks to Dan and Redu I was able to put together an example that consumes data incrementally, using the Fetch API . The caveat is that this will not work on Internet Explorer, and it has to be enabled by the user in Firefox:

   /** This works on Edge, Chrome, and Firefox (from version 57). To use this example
    navigate to about:config and change

    - dom.streams.enabled preference to true
    - javascript.options.streams to true


    See https://developer.mozilla/en-US/docs/Web/API/ReadableStream
*/

fetch('http://localhost:8081/numbers').then(function(response) {

  console.log(response);

  const reader = response.body.getReader();

  function go() {
    reader.read().then(function(result) {
      if (!result.done) {
        var num = JSON.parse(
          new TextDecoder("utf-8").decode(result.value)
        );
        console.log(
          "Got number " + num.intVal
        );        
        go ();
      }
    })
  }

  go ();
})

The full example (with the server) is available at my sandbox. I find it illustrative of the limitations of XMLHttpRequest to pare this version with the this one, which does not use the fetch API.

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>