Send File From ExpressJS Response
ExpressJS is a popular web framework for NodeJS. It's lightweight and easy to use.
It provides a varies of ways of sending files to the client, and access can be controlled.
Serve Static Files
The most common way to serve static files is to use the express.static middleware.
To serve static files such as images, CSS files, and JavaScript files, use the express.static built-in middleware function in Express.
jsconst express = require('express');
const app = express();
// Serve static files from the public directory
app.use(express.static('public'));
Send File
The res.sendFile method can be used to send a file to the client.
Transfers the file at the given path. Sets the Content-Type response HTTP header field based on the filename’s extension. Unless the root option is set in the options object, path must be an absolute path to the file.
jsconst express = require('express');
const app = express();
app.get('/files/:filename', (req, res) => {
const filename = req.params.filename;
// Send a file on the server file path to the client
res.sendFile(
`/path/to/file/${filename}` // Path to the file on the server
);
});
Download File
The res.download method can be used to download a file to the client.
Transfers the file at path as an “attachment”. Typically, browsers will prompt the user for download. By default, the Content-Disposition header “filename=” parameter is derrived from the path argument, but can be overridden with the filename parameter. If path is relative, then it will be based on the current working directory of the process or the root option, if provided.
jsconst express = require('express');
const app = express();
app.get('/files/:filename', (req, res) => {
const filename = req.params.filename;
// Download a file on the server file path to the client
res.download(
`/path/to/file/${filename}`, // Path to the file on the server
filename, // Set the filename of the downloaded file, browser will save the file with this name
);
});
Response with a File Stream
Response is actually a Writable Stream, so you can pipe a readable stream to it.
Browsers will display images sent in this way directly rather than downloading them, because it does not set any headers like Content-Disposition
to tell browsers to download the image as a file.
WARNING
Serving files through a stream is not a recommended practice. It is inefficient while streaming video files.
Instead, you should use the response.sendFile() method.
jsconst express = require('express');
const mime = require('mime');
const fs = require('fs');
const app = express();
app.get('/files/:filename', (req, res) => {
const filename = req.params.filename;
const type = mime.getType(filename);
res.writeHead(200, {
'Content-Type': type,
'Content-Disposition': 'attachment; filename=yourFileName.txt',
'Content-Length': stat.size
});
fs.createReadStream(filepath).pipe(res); // Pipe file stream to response
});
Access Control
If you would like to add an access control, just add a middleware before the middleware that sends files or do it within the middleware.
jsconst express = require('express');
const app = express();
// Add access control to everything behind path the path you would like to protect
app.use('/', (req, res, next) => {
// Do your access control here ...
// Call next() to allow the request to continue
next();
});
// Serve static files from the public directory
app.use(express.static('public'));
app.get('/files/:filename', (req, res) => {
// do something to control access...
const filename = req.params.filename;
// Download a file on the server file path to the client
res.download(
`/path/to/file/${filename}`, // Path to the file on the server
filename, // Set the filename of the downloaded file, browser will save the file with this name
);
});