2016-06-28 37 views
0

我有一个负责解析和导入CSV文件的路由的Express.js服务器。Streaming Node.js通过XHR对客户端的响应

我想将导入过程的状态实时回报给用户的浏览器。

从Express.js流反应是直截了当:

router.get('/test', function(_req, _res, _next) { 
    _res.write('File import initiated.'); 

    // ... processing CSV in loop 

    _res.write('Processing row x.'); 

    // artificial delay to simulate some i/o 
    setTimeout(function() { 
     _res.write('File import completed successfully.'); 
     _res.end(); 
    }, 2000) 
}); 

发送HTTP请求到端点通过卷曲按预期工作。在上述示例中,立即收到两个流式响应 ,然后在两秒钟后收到最终响应。

但是,浏览器(Chrome)并非如此。使用jQuery $.ajax和一个原始XHR调用进行测试,整个 响应似乎被缓存,并在响应完成时一次全部返回。

这种类型的通信通常如何处理?我认为socket.io是一个选项,但肯定有一个简单的方法来缩小浏览器的构建int XHR或XHR2功能吗?

+1

不要相信目前可以使用'XHR'单独使用单个请求的过程,但应该可以使用多个请求。请参阅http://stackoverflow.com/questions/35899536/method-for-streaming-data-from-browser-to-server-via-http/。 – guest271314

+0

参见https://github.com/yutakahirano/fetch-with-streams/issues/30。您可以从服务器请求,直到收到文件的总字节数,然后重新组装文件客户端。 – guest271314

+0

https://jakearchibald.com/2016/streams-ftw/#streams-the-fetch-api,http://jsbin.com/vuqasa/edit?js,console – guest271314

回答

1

您可以将引用ID返回给客户端,客户端调用正确的http api来收集该csv处理请求的状态。您可能需要一些后端支持来启用此功能。就像数据库中的一些表可以跟踪这种状态。

router.get('/test', function(_req, _res, _next) { 
    SaveFile(_res.file).then(function(id) { 
     _res.end(JSON.stringify({id: id}); 
    }); 
}); 

router.get('/status', function(_req, _res, _next) { 
    GetStatus(_res.params.id).then(function(status) { 
     _res.end(JSON.stringify(status)); 
    }); 
}); 

否则,如果你仍然想要实时,请使用websockets。你必须设计你期望的沟通形式。

+0

好主意。我决定采用websockets来实时推送数据。 –