ldd
ldd

Reputation: 109

Node js: write zip file (stored in a variable as Buffer) in a new window

I know I have a very pretty buffer that , if written directly to a file, gives me an acceptable zip file:

fs.writeFile("acceptable.zip", prettyBuffer);
//file acceptable.zip is a valid zip file

how can I provide this very prettyBuffer as a download for the user?

I tried

var uriContent = "data:application/zip," + prettyBuffer);  
window.open(uriContent)

and

var uriContent = "data:application/octet-stream," + prettyBuffer);  
window.open(uriContent)

and at least 10 variations with different encodings and it still won't work!

edit:

Here's my code

var AdmZip = require('adm-zip');
var zip = new AdmZip();  
zip.addFile("row0", new Buffer("hi"), "comment");  
var prettyBuffer = zip.toBuffer()
var uriContent = "data:application/zip;base64," + prettyBuffer.toString('base64');

var encodedUri = uriContent;  
var link = document.createElement("a");  
link.setAttribute("href", encodedUri);  
link.setAttribute("download", "acceptable.zip");  
link.click(); 

Upvotes: 0

Views: 5941

Answers (2)

igorpavlov
igorpavlov

Reputation: 3626

Why you are using WINDOW in NodeJS?

1) Try setting proper response header:

response.writeHead(200, {'Content-Type': 'application/zip'})

2) Then send you buffer:

response.end(buffer)

3) On client side use something like:

<a target="_blank" href="file_URL">Download file</a>

Upvotes: 1

mak
mak

Reputation: 13405

Encode it in base64:

console.log('<a href="data:application/zip;base64,' + prettyBuffer.toString('base64') + '" download="acceptable.zip">');

download is a new attribute in HTML5.

This attribute, if present, indicates that the author intends the hyperlink to be used for downloading a resource. If the attribute has a value, the browser should interpret that as the default filename that the author recommends for use in labeling the resource in a local file system. There are no restrictions on allowed values, but you should consider that most file systems have limitations with regard to what punctuation is supported in file names, and browsers are likely to adjust file names accordingly.

You can use this with data:, blob: and filesystem: URLs, to make it easy for users to download programmatically generated content.

If you use the http module, you must write the buffer to the response body. Use response.write().

var http = require('http');

var prettyBuffer = ...;

http.createServer(function (req, res) {
  if (req.path == '/acceptable.zip') {
    res.writeHead(200, {
      'Content-Type': 'application/octet-stream',
      'Content-Length': prettyBuffer.length,
      'Content-Disposition': 'attachment; filename=acceptable.zip'
    });
    res.write(prettyBuffer);
    res.end();
  } else {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
  }
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

Upvotes: 0

Related Questions