node.js - File Downloads on iOS Firefox Show "Unknown" Filename and Incorrect File Size - Stack Overflow

I'm working on a file download feature in my Node.js + Express backend and React frontend. The dow

I'm working on a file download feature in my Node.js + Express backend and React frontend. The download works fine on most browsers, but I’m experiencing the following issues only on iOS Firefox:

The filename appears as "Unknown" instead of the expected filename. The file size initially displays correctly before the download starts, but the downloaded file is much smaller than expected (e.g., it should be several MB but downloads as 187KB). The downloaded file appears to be empty.

Backend Code (Node.js + Express) I'm using fs.createReadStream to stream the file to the response:

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

exports.downloadFile = (req, res, next) => {
    try {
        console.log('Download endpoint hit');

        const filepath = req.body.filepath;
        const filename = path.basename(filepath);
        const encodedFilename = encodeURIComponent(filename).replace(/%20/g, ' ');

        let stat;
        try {
            stat = fs.statSync(filepath);
        } catch (err) {
            console.error('File not found:', filepath);
            return res.status(404).json({ success: false, msg: 'File not found' });
        }

        res.status(200);
        res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodedFilename}`);
        res.setHeader('Content-Type', 'application/octet-stream';);
        res.setHeader('Accept-Ranges', 'bytes');
        res.setHeader('Content-Length', stat.size);
        res.flushHeaders();

        const fileStream = fs.createReadStream(filepath);

        fileStream.pipe(res);

        fileStream.on('error', (err) => {
            console.error('File stream error:', err);
            if (!res.headersSent) {
                res.status(500).json({ success: false, msg: 'File download failed' });
            }
        });

        fileStream.on('end', () => {
            console.log('File sent successfully.');
            res.end();
        });

    } catch (error) {
        next(error);
    }
};

Frontend Code (React) On the frontend, I'm handling the download like this:

.then((response) => {
    const blob = new Blob([response.data], { type: response.headers['content-type'] });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filenames[index];
    link.click();

    setTimeout(() => {
        link.remove();
        URL.revokeObjectURL(url); // Release memory
    }, 500);
})
.catch((error) => {
    console.error(`Error downloading file ${filenames[index]}:`, error);
});

  • Checked that Content-Disposition is properly set (filename*=UTF-8''${encodedFilename}).
  • Ensured that Content-Length is correctly set to the actual file size.
  • Verified that fs.createReadStream(filepath) correctly reads the file.
  • Tried using a plain res.download(filepath) instead of fs.createReadStream, but the issue persists.
  • Tested on Chrome/Safari on iOS and everything works fine—only Firefox on iOS has this issue.

Questions:

  • Why does only iOS Firefox show "Unknown" as the filename?
  • Why is the downloaded file empty or much smaller than expected?
  • Is there an alternative way to handle file downloads that works consistently across browsers, especially on iOS Firefox?
  • Any help would be greatly appreciated! Thanks in advance.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744907225a4600329.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信