Create a text file in node.js from a string and stream it in response
Asked Answered
P

4

35
  1. I am using express.js

  2. I have a string "Hello world!"

  3. I want a user to click on

    <a href=/download>Download</a>
    
  4. The user should get Hello.txt download with the text in it, NOT open a tab with the text.

  5. I have looked around for ways to achieve this, I am guessing it has something to do with creating readstreams from buffer and piping to response, but I most of the examples dealt with reading actual files from disk, I don't want to read from disk, i just want to respond with a file created from a string.

Thanks!

Pestilent answered 22/2, 2014 at 5:15 Comment(4)
Do you want to create a download link and make the user to download the file?Floriaflorian
Yeah download link, but creating a download link is not the main issue, how do i convert string "Hello World!" to a text file in response in expressjs.Pestilent
try to use socket.io and send the txt file as a socket message instead of relying to req-res moduleFloriaflorian
The question is how do you create THAT txt file.Pestilent
B
49

I think I understand what you're trying to do. You want to send a .txt file to the client without actually creating a file on disc.

This is actually pretty basic, and extremely easy. All you have to do is set your MIME type in the header, however most browsers don't download .txt files by default. They just open and display the contents.

var text={"hello.txt":"Hello World!","bye.txt":"Goodbye Cruel World!"};
app.get('/files/:name',function(req,res){
   res.set({"Content-Disposition":"attachment; filename=\"req.params.name\""});
   res.send(text[req.params.name]);
});

As a future note, you can send any data that's stored as a variable. If you have a buffer loaded with an image, for example, you can send that the same way by just changing the Content-Type, otherwise the browser has no idea what data you're sending, and express I believe sets the default type to text/html. Here is a good reference to Internet Media Types and MIME types.

Baneful answered 22/2, 2014 at 6:56 Comment(6)
"Content-Disposition":"attachment; filename=\"Hello.txt\"" will help, but only in some browsers.Consistent
Hey thanks for this, up you got it right and i think your answer is almost there, except that i wanted to name the file too.Pestilent
If this answer solved your problem could you please mark this as the solution?Baneful
I think Content-type should be specified too. Some browsers like safari will add .html extension to file name. In my case I set: res.set({'Content-Disposition': 'attachment; filename=2015.csv','Content-type': 'text/csv'});Pyatt
This worked. Tiny note for future, I found it was necessary to include the double quotes around the filename, e.g. res.set({'Content-Disposition': 'attachment; filename=\"2015.csv\"','Content-type': 'text/csv'});Unwitting
@majorBummer It looks like (based on some docs; I haven't tested it) it now works in the current version of every major browser. I believe IE and Firefox had quirky behaviors when I wrote that comment.Consistent
K
15

Try this:

router.get('/download', (req, res) => {
  var text = 'Hello world!'
  res.attachment('filename.txt')
  res.type('txt')
  res.send(text)
})
Karlynkarma answered 6/4, 2018 at 3:58 Comment(0)
A
10

this is working for me !

var text="hello world";

res.setHeader('Content-type', "application/octet-stream");

res.setHeader('Content-disposition', 'attachment; filename=file.txt');

res.send(text);
Airily answered 26/4, 2017 at 10:52 Comment(1)
This one worked well!Perpetuity
P
3

Thanks for the help guys, this is what i ended up with: @aaron, is there a way for disposition to work in all browsers?

res.setHeader('Content-disposition', 'attachment; filename=theDocument.txt');
res.setHeader('Content-type', 'text/plain');
res.charset = 'UTF-8';
res.write("Hello, world");
res.end();
Pestilent answered 22/2, 2014 at 7:1 Comment(1)
You specified that you were using express. If you're going to use express, I recommend actually using it. What you are doing is pure node.jsBaneful

© 2022 - 2024 — McMap. All rights reserved.