使用 NodeJS 正确发送文件
Proper send file with NodeJS
考虑以下相当简单的中间件:
(req, res, next) => {
const stream = fs.createReadStream(req.filePath)
await new Promise((resolve, reject) => stream
.on('error', reject)
.on('end', resolve)
.pipe(res, { end: false })
.on('error', reject)
// 'close' is emitted if client prematurely disconnects.
.on('close', resolve)
res.end()
}
有几个问题我不确定如何处理:
- 如果 res 在这个中间件 运行s 之前已经发出 'close',它将被卡住。
- 如果 res 发出
close
或 error
源流是如何清理的? autoClose
只会 运行 在 end
上 运行 如果所有数据都已读取,则只会 运行 。但是,如果目标失败,如何将其传播到源?我应该始终在源流上调用 destroy
吗?
这似乎可以解决问题:
import onFinished from 'on-finished'
(req, res, next) => {
const stream = fs.createReadStream(req.filePath)
onFinished(res, () => stream.destroy && stream.destroy())
if (onFinished.isFinished(res)) {
return
}
await new Promise((resolve, reject) => stream
.on('error', reject)
.on('end', resolve)
.pipe(res, { end: false })
.on('error', reject)
// 'close' is emitted if client prematurely disconnects.
.on('close', resolve)
res.end()
}
考虑以下相当简单的中间件:
(req, res, next) => {
const stream = fs.createReadStream(req.filePath)
await new Promise((resolve, reject) => stream
.on('error', reject)
.on('end', resolve)
.pipe(res, { end: false })
.on('error', reject)
// 'close' is emitted if client prematurely disconnects.
.on('close', resolve)
res.end()
}
有几个问题我不确定如何处理:
- 如果 res 在这个中间件 运行s 之前已经发出 'close',它将被卡住。
- 如果 res 发出
close
或error
源流是如何清理的?autoClose
只会 运行 在end
上 运行 如果所有数据都已读取,则只会 运行 。但是,如果目标失败,如何将其传播到源?我应该始终在源流上调用destroy
吗?
这似乎可以解决问题:
import onFinished from 'on-finished'
(req, res, next) => {
const stream = fs.createReadStream(req.filePath)
onFinished(res, () => stream.destroy && stream.destroy())
if (onFinished.isFinished(res)) {
return
}
await new Promise((resolve, reject) => stream
.on('error', reject)
.on('end', resolve)
.pipe(res, { end: false })
.on('error', reject)
// 'close' is emitted if client prematurely disconnects.
.on('close', resolve)
res.end()
}