avatar

ShīnChvën ✨

Effective Accelerationism

Powered by Druid

Send File From ExpressJS Response

Wed Oct 19 2022

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.

const 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.

const 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.

const 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.

const 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.

const 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
  );
});