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> 点击下载