The node server uses pipe to send the file stream to the front end, and how should the front end receive it

as mentioned, after the file is converted into a file stream on the node side and transferred to res through pipe , the front end configures xhr, but the response received prints the size to 0 according to the referenced data;
node get interface code is as follows:

app.get("/api/download",function(req, res, next){
        var currDir = path.join(__dirname,req.query.dir),
            fileName = req.query.name,
            currFile = path.join(currDir,fileName),
            stats = fs.statSync(currFile);
        fs.exists(currFile,function(exist) {
            if(exist){
                res.set({
                    "Content-type":"application/octet-stream",
                    "Content-Disposition":"attachment;filename="+encodeURI(fileName),
                    "Content-Length": stats.size
                });
                let fReadStream = fs.createReadStream(currFile);
                fReadStream.pipe(res);
            }else{
                res.set("Content-type","text/html");
                res.send("file not exist!");
                res.end();
            }
        });
    });

the key code returned by the front-end receiver is as follows:

                        var xhr = new XMLHttpRequest();    
                        xhr.open("get", "/api/download?dir="+response.data.dir+"&name="+response.data.fileName, true);
                        xhr.responseType = "blob";
                        xhr.onload = function() {
                            if (this.status == 200) {
                                var blob = this.response;
                                console.log(blob);
                    }};
                    xhr.send();

at this point, the blob printed by the front-end console is

.

but if you comment out the pipe on the node side, enter the following code, and the front end will get the blob with size.

//fReadStream.pipe(res);
res.send("testtesttesttest")

-Update Line-

A deeper manifestation of the problem is to directly input the stitched url in get mode into the browser and download it directly. In this case, the size of the file stream obtained by Node is not 0, but the size of the node file stream obtained through the xhr request written above is 0. There is also no difference between the two file paths obtained after careful inspection, so there is something wrong with the request method?

reference link is https://www.cnblogs.com/cdemo.

Feb.28,2022

end of the question, post by yourself
first of all, there is no problem with these two pieces of code. Some people will ask you if there is no question. Where did you report the mistake?
Don't worry. The application scenario is like this, all digging holes for yourself

  1. the underlying logical data request interface is written by Java, that is, the original file exists on the Java server
  2. due to the need of work, the data acquisition operation at the front end requires the node server to do intermediate forwarding
  3. the Java interface uses post to request download
  4. at the beginning, I didn't know how to use post to request download, so I took the initiative to take a stupid approach: click on the front end to download, and node gets the parameters from post to download the file to node and return the front-end file address and file name. The front end gets the response and splices it into a get request to simulate the a tag to click to download the file in the node, and then delete the corresponding file on the node side after the download is completed.
  5. so I can't help scolding myself for being stupid and digging a hole for myself. If I ask for a download back and forth, the traffic double, is really a loser.
  6. so the problem lies in that the process of step 4 is completed after the front end clicks to download, there is no delay in waiting, the requests are all asynchronous, and the post/get interfaces written on the node side use pipe to process the file transfer.
  7. so as soon as the frontend clicks, node receives the frontend request and requests data from the Java side. At this time, because of the pipe, there is already data in the response and the data is returned. After receiving the data, the frontend starts to splice the get request url and click on the a tag to download it, and then go to the node end to find the corresponding file. At this time, the file on the node side may not have been transferred, so the source file size obtained in the get request in node is 0. Then came the above problems.

as for how to achieve the final download, it is very simple. the front end simulates the form to download post request data , and the post interface on the node side directly resFromJava.pipe. (resFromNode) the requested file stream. The front end does not need to do any other processing to start the download event of the browser. When I write here, I really want to hammer myself

.
Menu