You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js文件下载接口出现Requires Range header错误如何解决?

问题解决:Node.js下载接口兼容Range请求与完整文件下载

你的接口在VLC中能正常流式播放文件,但直接通过链接访问下载时返回“Requires Range header”错误,核心原因是当前代码强制要求请求必须携带Range头——VLC这类流媒体播放器会主动发送Range请求实现分段加载,但普通浏览器直接发起的下载请求通常不会自动添加该头。

修改后的代码如下:

const path = require('path');
const fs = require('fs');
const rangeParser = require('range-parser');

app.get('/download-file', (req, res) => {
  const filePath = req.query.file;

  if (!filePath) {
    res.status(400).send('File path is required');
    return;
  }
  const fullPath = path.resolve(filePath);
  fs.stat(fullPath, (err, stats) => {
    if (err) {
      res.status(404).send('File not found');
      return;
    }
    const fileSize = stats.size;
    const rangeHeader = req.headers.range;

    // 兼容两种请求场景:带Range头返回分段内容,不带则返回完整文件
    if (!rangeHeader) {
      // 返回完整文件逻辑
      res.status(200);
      res.setHeader('Content-Length', fileSize);
      res.setHeader('Content-Type', 'application/octet-stream');
      res.setHeader('Content-Disposition', `attachment; filename="${path.basename(filePath)}"`);
      const stream = fs.createReadStream(fullPath);
      stream.pipe(res);
      req.on('close', () => {
        stream.destroy();
        console.log('Request canceled by the client');
      });
      return;
    }

    // 原有Range请求处理逻辑保留
    const ranges = rangeParser(fileSize, rangeHeader);
    if (ranges === -1) {
      res.status(416).send('Range not satisfiable');
      return;
    }
    if (ranges === -2 || !ranges.length) {
      res.status(400).send('Malformed Range header');
      return;
    }
    const range = ranges[0];
    const { start, end } = range;
    res.status(206);
    res.setHeader('Content-Range', `bytes ${start}-${end}/${fileSize}`);
    res.setHeader('Accept-Ranges', 'bytes');
    res.setHeader('Content-Length', end - start + 1);
    res.setHeader('Content-Type', 'application/octet-stream');
    res.setHeader('Content-Disposition', `attachment; filename="${path.basename(filePath)}"`);
    const stream = fs.createReadStream(fullPath, { start, end });
    stream.pipe(res);
    req.on('close', () => {
      stream.destroy();
      console.log('Request canceled by the client');
    });
  });
});

关键修改说明:

  • 移除了对Range头的强制校验,新增完整文件返回逻辑,适配普通浏览器的直接下载请求
  • 完整文件返回时设置状态码200,Content-Length设为文件总大小,保持下载相关头信息一致
  • 保留原有Range请求处理逻辑,确保VLC等流媒体播放器仍能正常流式播放

内容的提问来源于stack exchange,提问作者alfardo caseman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:50:59