简体   繁体   English

尝试使用 Node.js 下载 PDF 文件时出现“无文件”或空文件

[英]Getting "No file" or empty file when trying to download PDF file with Node.js

The issue:问题:

I need to download a PDF file from my server but getting either "No file" or empty file我需要从我的服务器下载一个 PDF 文件,但得到“无文件”或空文件

Details:细节:

Here is my server-side code:这是我的服务器端代码:

let fileBuffered = '';

// authentication for downloading a file from Dropbox API to my server
    const dropbox = dropboxV2Api.authenticate({
        token: process.env.DEV_DROPBOX_SECRET_KEY
    });

    // configuring parameters
    const params = Object.freeze({
        resource: "files/download",
        parameters: {
            path: `/${customerFileFolder}/${fileName}`
        }
    });

    let dropboxPromise = new Promise(function (resolve, reject) {
        dropbox(params, function (err, result) {
            if (err) {
                reject(err);
            } else {
                resolve(result);
            }
        }).on('data',function(data) {
                fileBuffered += data;
        })
    const file = fileBuffered;

    res.setHeader("Content-Type", "application/octet-stream");
    res.send(file);

The PDF file's that I'm trying to download size is 139,694 bytes.我尝试下载的 PDF 文件大小为 139,694 字节。 The length of the fileBuffered variable is 132,597. fileBuffered 变量的长度是 132,597。 Here is the content of the variable as it is shown in the debugger:这是调试器中显示的变量内容: 在此处输入图像描述 Seems like a legit PDF file似乎是合法的 PDF 文件

Here is the client-side这是客户端

function documentFileDownload(fileName) {
    const ip = location.host;
    let request = $.ajax({
        type: "POST",
        url: `${http() + ip}/documentFileDownload`,

        headers: {
            "Accept": "application/octet-stream"
        },


        data: {
            fileName: fileName
        },
        error: function (err) {
            console.log("ERROR: " + err);
        }
    });

    console.log(request);

    return request;
}

Problem: Then I get the response on a client-side it looks like this:问题:然后我在客户端得到如下响应:

在此处输入图像描述

Note the size of the responseText: 254Kb.请注意响应文本的大小:254Kb。 What I actually get in the browser is a "Failed - No file" message我在浏览器中实际得到的是“失败 - 无文件”消息

在此处输入图像描述

What else I tried:我还尝试了什么:

I tried to play with different Content-Types (application/pdf, text/pdf) on a server-side and tried to convert the variable to base64 buffer我尝试在服务器端使用不同的内容类型(应用程序/pdf、文本/pdf)并尝试将变量转换为 base64 缓冲区

const file = `data:application/pdf;base64, ${Buffer.from(fileBuffered).toString("base64")}`;

and added res.setHeader("Accept-Encoding", "base64");并添加了res.setHeader("Accept-Encoding", "base64"); but still getting the same result.但仍然得到相同的结果。

Any ideas?有任何想法吗?

I found a solution.我找到了解决办法。 I missed a .on("end", ) event while reading data from Dropbox stream. Here is a working solution:我在从 Dropbox stream 读取数据时错过了.on("end", )事件。这是一个可行的解决方案:

Here is the server-side:这是服务器端:

let chunk = [];
let fileBuffered = '';

// authentication for downloading a file from Dropbox API to my server
    const dropbox = dropboxV2Api.authenticate({
        token: process.env.DEV_DROPBOX_SECRET_KEY
    });

    // configuring parameters
    const params = Object.freeze({
        resource: "files/download",
        parameters: {
            path: `/${customerFileFolder}/${fileName}`
        }
    });

    let dropboxPromise = new Promise(function (resolve, reject) {
        dropbox(params, function (err, result) {
            if (err) {
                reject(err);
            } else {
                resolve(result);
            }
        }).on('data',function(data) {
                fileBuffered += data;
        }).on('end', () => {
                // console.log("finish");\
                // generate buffer
                fileBuffered = Buffer.concat(chunk);
            });

    const file = `data:application/pdf;base64, ${Buffer.from(fileBuffered).toString("base64")}`;
    res.setHeader("Content-Type", "application/pdf");
    res.send(file);

Client-side:客户端:

function documentFileDownload(fileName) {
    const ip = location.host;
    let request = $.ajax({
        type: "POST",
        url: `${http() + ip}/documentFileDownload`,
        responseType: "arraybuffer",
        headers: {
            "Accept": "application/pdf"
        },

        data: {
            fileName: fileName
        },
        error: function (err) {
            console.log("ERROR: " + err);
        }
    });

    // console.log(request);
    return request;
}

Try adding dataType: "blob" in your $.ajax method尝试在 $.ajax 方法中添加dataType: "blob"

and within the headers object add this 'Content-Type', 'application/json' .并在标头 object 中添加此'Content-Type', 'application/json'

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

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