Node.js 进度指示器反馈

8

我有一个关于使用Node.js 'request'发送的问题。我有一个作为代理的Node.js应用程序,实际上将请求体转发到另一个服务器。我想要查看上传操作的进度。现在我正在做如下处理:

BROWSER 
   -> UPLOAD TO NODE 
   -> UPLOAD TO 3rd PARTY SERVICE 
   -> RETURN 3rd PARTY RESPONSE TO BROWSER

如果可能的话,我会记录并在console.log中检查完成进度。但是,是否也可以返回一个

res.send(progress)

同时,在等待上传完成并发送客户端上传成功的过程中?

BROWSER 
   -> UPLOAD TO NODE
   -> UPLOAD TO 3rd PARTY SERVICE 
       -> RETURN progress <- 
       -> RETURN progress <- 
       ...etc.
   -> RETURN 3rd PARTY RESPONSE TO BROWSER

这是上传代码(非常直接)。
var requestOptions = {
    timeout: 120000,
    url: url, //URL to hit
    method: 'post',
    headers: headers,
    body: payload //Set the body as a string
};


request(requestOptions, function (error, response, body) {
    if (error) {
        res.send(error);
    }
    else {
        //res.sendStatus(response.statusCode);
        console.log("[RETURNING RESPONSE BODY]");
        res.send(body);
    }
});

使用res.write()发送请求更新。当上传完成后,使用res.end() - AdityaParab
2个回答

10

您的问题包含两个部分。其中一个是获取请求的进度,可以在此处找到:上传进度 - 请求

另一部分是通知浏览器进度。HTTP协议不允许您发送多个响应,因此使用res.send(progress)是不可能的。

但是,您可以保持发送部分响应直到完成。向没有关闭的res写入内容就像res.write("string")那么简单,但是访问响应可能更加困难:使用AJAX或WebSockets访问部分响应?

您还需要一种方法来包装来自后端服务器的主体(以及错误),以便它可以适合作为最终部分响应。

另一种解决方案是打开另一个WebSocket请求以跟踪上传/下载进程。socket.io是用于此目的的Node.js的好库。


谢谢。第一个链接让我找到了第一部分的解决方案。所以我需要将它看作两个部分,这很有道理。我会研究一下socket.io。 - Riël
这比其他的好多了,只是缺少与链接中回答相关的内容。 - dewwwald

1

第一部分的解决方案在r.req.connectin.bytesWritten中。

var r = request(requestOptions, function (error, response, body) {
    clearInterval(q);
    ...
});

var q = setInterval(function () {
    console.log("Uploaded: " + r.req.connection.bytesWritten);
}, 250);

1
虽然你正在实现的逻辑是正确的,但这不是正确的答案,因为你在服务器上使用了 console.log。用户希望它在浏览器中显示。 :) - AdityaParab
啊,当我是 OP 时,你有点正确。但我认为这会是我问题的第一个部分的解决方案。我做对了吗? :) - Riël
1
加油,@Riel 是 OP。我相信他或她会找到正确的方法来改进服务器到客户端的进度报告。;-) - FelisCatus
@Riël,我正在尝试获取请求的bytesWritten,但我只得到了FormData的总大小...我不知道我做错了什么...也尝试了_bytesDispatched,但结果相同...你知道可能是什么问题吗?我正在上传一个formdata文件(二进制)。 - Enrique

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接