简体   繁体   English

通过XHR将Node.js响应流式传输到客户端

[英]Streaming Node.js response to client over XHR

I have an Express.js server with a route that is responsible for parsing and importing a CSV file. 我有一个Express.js服务器,其路由负责解析和导入CSV文件。

I'd like to report the status of the import process in realtime back to the user's browser. 我想向用户浏览器实时报告导入过程的状态。

Streaming responses from Express.js is straight forward: 来自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 )
} );

Sending a HTTP request to the endpoint via CURL works as expected. 通过CURL向端点发送HTTP请求按预期方式进行。 In the above example two streamed responses are received immediately, followed by the final response after two seconds. 在上面的示例中,两个流式响应立即被接收,两秒钟后是最终响应。

This is not the case in the browser (Chrome) however. 但是,在浏览器(Chrome)中不是这种情况。 Testing both with jQuery $.ajax , and a raw XHR call, the entire response appears to be buffered and returned all at once when the response is complete. 使用jQuery $.ajax和原始XHR调用进行测试,整个响应似乎已被缓冲并在响应完成后立即全部返回。

How is this type of communication normally handled? 通常如何处理这种类型的通信? I assume socket.io is an option, but surely there's a simpler way to utalise the build int XHR or XHR2 features of the browser? 我假设使用socket.io是一个选项,但是肯定有一种更简单的方法来实现浏览器的内置int XHR或XHR2功能?

You can give back a reference id to the client, and the client calls the correct http api's to gather the status of that csv processing request. 您可以将参考ID返回给客户端,然后客户端调用正确的http api来收集该csv处理请求的状态。 You might want some backend support to enable this. 您可能需要一些后端支持来启用此功能。 Something like some tables in the database that can track this status. 诸如数据库中某些表之类的可以跟踪此状态的东西。

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));
    });
});

Else, if you still want realtime, employ websockets. 另外,如果您仍然想实时使用,请使用websocket。 You've to design the form of communication you expect. 您必须设计期望的沟通形式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM