1

The issue:

I need to download a PDF file from my server but getting either "No file" or empty file

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. The length of the fileBuffered variable is 132,597. Here is the content of the variable as it is shown in the debugger: enter image description here Seems like a legit PDF file

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:

enter image description here

Note the size of the responseText: 254Kb. What I actually get in the browser is a "Failed - No file" message

enter image description here

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

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

and added res.setHeader("Accept-Encoding", "base64"); but still getting the same result.

Any ideas?

2 Answers 2

1

I found a solution. I missed a .on("end", ) event while reading data from Dropbox stream. Here is a working solution:

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; } 
Sign up to request clarification or add additional context in comments.

Comments

0

Try adding dataType: "blob" in your $.ajax method

and within the headers object add this 'Content-Type', 'application/json'.

1 Comment

Thanks, Shijil. I tried dataType: "blob" but it doesn't help. I found a solution and will post an answer shortly

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.