Skip to content

Node.js 文件流下载

通过文件流方式实现文件下载,适用于大文件或实时生成内容的场景。

两个关键响应头

响应头说明
Content-Type指定文件 MIME 类型
Content-Disposition控制浏览器处理方式

Content-Disposition 取值

效果
attachment;filename=xxx触发下载,浏览器保存为文件
inline浏览器内直接打开(图片/PDF 等)

后端代码

js
import express from 'express'
import cors from 'cors'
import fs from 'node:fs'
import path from 'node:path'

const app = express()
app.use(cors())
app.use(express.json())

app.post('/download', (req, res) => {
  const fileName = req.body.fileName
  const filePath = path.join(process.cwd(), './static', fileName)
  const content = fs.readFileSync(filePath)

  res.setHeader('Content-Type', 'application/octet-stream')    // 二进制流
  res.setHeader('Content-Disposition', `attachment;filename=${fileName}`)
  res.send(content)
})

app.listen(3000)

前端代码

js
fetch('http://localhost:3000/download', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ fileName: 'test.png' })
})
  .then(res => res.arrayBuffer())       // 响应以二进制流接收
  .then(data => {
    const blob = new Blob([data])        // 转 Blob
    const url = URL.createObjectURL(blob) // 生成临时 URL
    const a = document.createElement('a')
    a.href = url
    a.download = 'test.png'             // 下载文件名
    a.click()                            // 触发下载
    URL.revokeObjectURL(url)             // 释放内存
  })

流程

POST /download (请求文件名)
  → 服务端读取文件
  → 设置 Content-Type + Content-Disposition: attachment
  → 返回二进制流
前端
  → res.arrayBuffer() 接收
  → Blob → URL.createObjectURL → 模拟 <a> 点击下载