Node.js/Express File Download Returns 0-Byte Plaintext Files

29 Views Asked by At

When I trigger a file download from my frontend (utilizing a React app and an async Redux action for the download), the download initiates but the resulting file is always 0 bytes and is of a plaintext format, not matching the original file's content or MIME type.

Here's the core part of my download implementation in the Express backend:

const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();

const UploadFolder = '/path/to/uploads'; // Adjusted to my actual upload folder path

app.get('/download/:filename', async (req, res, next) => {
  const { filename } = req.params;
  const filePath = path.join(UploadFolder, filename);

  if (!fs.existsSync(filePath)) {
    return res.status(404).json({ error: 'File not found' });
  }

  res.setHeader('Content-Type', 'application/octet-stream');
  res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);

  const readStream = fs.createReadStream(filePath);
  readStream.pipe(res);

  readStream.on('error', (error) => {
    console.error(`Error reading file: ${error}`);
    next(error);
  });
});
  • I've verified the file paths and ensured the files exist and are accessible by the server.
  • I've checked that the MIME type and headers are set correctly before piping the file stream.
  • I've tried using res.download(filePath) as an alternative, but the issue persists.
  • I've tried to detect the mime type and the file size and set them as content-type and content-length
1

There are 1 best solutions below

0
This Guy On

https://expressjs.com/en/api.html#res.download

can you use the built-in download() function?

const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();

const UploadFolder = '/path/to/uploads'; // Adjusted to my actual upload folder path

app.get('/download/:filename', async (req, res, next) => {
  const { filename } = req.params;
  const filePath = path.join(UploadFolder, filename);

  if (!fs.existsSync(filePath)) {
    return res.status(404).json({ error: 'File not found' });
  }
  
  res.download(filePath);
  
  });
});