简体   繁体   English

通过节点 js 将响应从 python flask 转发到客户端

[英]forwarding a response from python flask to client through node js

in a special scenario, my node js backend receives a response from python flask server.在特殊情况下,我的节点 js 后端收到来自 python Flask 服务器的响应。

I need to forward this response back to the client (as a response to an action that client preformed).我需要将此响应转发回客户端(作为对客户端执行的操作的响应)。

the response should start a download on the client browser for a file specified in python flask response body.响应应该在客户端浏览器上开始下载 python flask 响应正文中指定的文件。

The line of the return of the response from python flask: python烧瓶响应返回的行:

return flask.send_file(download_path, as_attachment=True, attachment_filename=file)

I get this response on my node server callback:我在我的节点服务器回调中收到此响应:

app.get(constants.routes.files.download, function (req, res) {
    fileController.downloadFile(req, (err, response_from_python) => {

        console.log("Response from python flask has arrived")
        res._headers = response_from_python.headers;
        res.set('Content-Disposition', 'attachment; filename=exmp_word.docx');
        return res.json(response_from_python.body)  

    });

This really triggers a download at client browser but the file is corrupted and can't be open with word (it was created with word..).这确实会在客户端浏览器上触发下载,但文件已损坏并且无法用 word 打开(它是用 word 创建的...)。 I think it's related to the way that file is encoded in response body (should I use res.json ?).我认为这与文件在响应正文中的编码方式有关(我应该使用res.json吗?)。

Also, if I connect from client directly to python-server (without going through node) than the file is downloaded successfully (isn't corrupted) but that isn't the way it should work (Should go through node server in the middle).另外,如果我从客户端直接连接到 python-server(不通过节点),那么文件会成功下载(没有损坏),但这不是它应该工作的方式(应该通过中间的节点服务器) .

How should I do this?我该怎么做?

Is there a way to pass the python response object directly to client without copying its body field to node res object and modify the headers?有没有办法将 python 响应对象直接传递给客户端,而无需将其正文字段复制到节点 res 对象并修改标头?

EDIT:编辑:

Thanks to Ivan Velichko I'ts working.感谢 Ivan Velichko 我没有工作。

Here is the modified function that does it (I have to build it better but the functionality exist).这是执行此操作的修改后的函数(我必须更好地构建它,但功能存在)。

app.get(constants.routes.files.download, function (req, res) {


res.set('content-Disposition', 'attachment; filename=noam_susp.docx');
res.set('content-type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
res.set('Accept-Ranges', 'bytes');
res.set('Cache-Control', 'public, max-age=0');
res.set('ETag', 'W/"2721-161b23de2ee');



var file_hash = req.params.identifier;

var request = http.get(constants.manager_rest_api.base_url +
    constants.manager_rest_api.get_file_endpoint +
    '/' + file_hash + '/download_inner', function(response) {
    response.pipe(res);
});

Looks like your solution makes a request to the python server, then reads the entire file content in memory and only then tries to send it back to the client using for some reasons res.json() .看起来您的解决方案向 python 服务器发出请求,然后读取内存中的整个文件内容,然后才尝试使用res.json()将其发送回客户端。 However, most probably you need only forward client's request to the python server and then forward python's response as-is.但是,很可能您只需要将客户端的请求转发到 python 服务器,然后按原样转发 python 的响应。 And you for sure should not download files on your node server.你肯定不应该在你的节点服务器上下载文件。 Instead use streams .而是使用 Something like:就像是:

app.get(constants.routes.files.download, function (req, res) {
    fileController.downloadFile(req).pipe(res);
});

To achieve this behaviour your fileController.downloadFile() should return a readable stream which you then can pipe() to the res .要实现此行为,您的fileController.downloadFile()应返回一个可读流,然后您可以通过pipe()将其发送到res And the res by itself is already a writable stream.res本身已经是一个可写的流。

UPD: it's important to copy headers from the python's response to the node's response explicitly before piping in it. UPD:在管道中明确地将头从 python 的响应复制到节点的响应是很重要的。

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

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