我有一个强制在浏览器中下载文件的功能,它适用于小文件,但不适用于大文件。下载开始时,我显示失败-没有文件,并且将其范围缩小了,原因是我正在设置206
状态代码(部分内容)。过去这种方法工作正常,但现在我收到无文件消息。
将其更改为状态代码200
时,将下载文件。在将状态代码保持为206
并删除Content-Disposition
时,该文件将在浏览器中播放。
下载时甚至还需要206
大文件吗?
export class Server {
private static async send(client: Client, req: http.IncomingMessage, res: http.ServerResponse) {
let fileSize = client.response.contentLength
let start = 0, end = fileSize - 1 < start ? start : fileSize - 1
if (fileSize > (this.app.chunkSize || 5e5)) {
let range = (req.headers.range || '') as string
let positions = range.replace(/bytes=/, '').trim().split('-')
start = parseInt(positions[0] || '0', 10)
end = parseInt(positions[1] || (fileSize - 1).toString(), 10)
let chunkSize = (end - start) + 1
// Setting the Code to 206 here breaks
client.response.setCode(206)
.setHeaders({
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
'Accept-Ranges': 'bytes',
'Connection': 'Keep-Alive',
'Content-Length': chunkSize
})
}
res.writeHead(client.response.code, <any>headers)
let { store, file } = client.response.fileStore
let stream: fs.ReadStream = store.readStream(file, { start, end })
.on('open', () => stream.pipe(res))
.on('close', () => res.end())
.on('error', err => res.end(err))
}
}
这里的读取流非常简单:
export default class extends Storage {
public readStream(filePath: string, options?: FileReadOptions) {
return fs.createReadStream(this.toPath(filePath), options)
}
}
答案 0 :(得分:1)
仅在浏览器明确请求时发送206
,否则发送200
if (!!req.headers.range) {
// if and only if client sends us range http reader in request,
// perform your logic, send 206
} else {
// forget about partial content here,
// pipe the file to res directly with 200
}