我有一个SailsJS后端,我在其中生成一个zip文件,这是我的前端(带有Redux的React App)请求的。 我正在使用Sagas进行异步调用并提取请求。 在后端,它尝试了以下操作:
//zipFilename is the absolute path
res.attachment(zipFilename).send();
要么
res.sendfile(zipFilename).send();
要么
res.download(zipFilename)send();
或通过以下方式传递流:
const filestream = fs.createReadStream(zipFilename);
filestream.pipe(res);
在我的前端,我尝试解析为:
parseJSON(response) => {
return response.clone().json().catch(() => response.text());
}
我尝试的所有内容都以一个空的zip文件结尾。 有什么建议么?
您尝试的选项存在各种问题:
res.attachment
只会设置Content-Type
和Content-Disposition
标头,但实际上不会发送任何内容。
您可以使用它来正确设置标题,但是您也需要将ZIP文件通过管道传递到响应中。
res.sendfile
: .send()
不应调用.send()
。 从官方文档的示例:
app.get('/file/:name', function (req, res, next) { var options = { ... }; res.sendFile(req.params.name, options, function (err) { if (err) { next(err); } else { console.log('Sent:', fileName); } }); });
如果正确构建了ZIP,则只要文件具有适当的扩展名,它就可以正常工作并设置适当的Content-Type
标头。
res.download
:同样,您不应在此之后调用.send()
。 从官方文档的示例:
res.download('/report-12345.pdf', 'report.pdf', function(err) { ... });
res.download
将使用res.sendfile
作为附件发送文件,从而设置Content-Type
和Content-Disposition
标头。
但是,您提到正在发送ZIP文件,但该文件为空,因此您可能应该检查是否正确创建了ZIP文件。 只要它们正确构建且扩展名为.zip
, res.download
应该可以正常工作。
如果要动态构建它们,请检查以下内容:
该中间件将动态创建一个包含多个文件的ZIP文件,并将其作为附件发送。 它使用lazystream
和archiver
const lazystream = require('lazystream');
const archiver = require('archiver');
function middleware(req, res) {
// Set the response's headers:
// You can also use res.attachment(...) here.
res.writeHead(200, {
'Content-Type': 'application/zip',
'Content-Disposition': 'attachment; filename=DOWNLOAD_NAME.zip',
});
// Files to add in the ZIP:
const filesToZip = [
'assets/file1',
'assets/file2',
];
// Create a new ZIP file:
const zip = archiver('zip');
// Set up some callbacks:
zip.on('error', errorHandler);
zip.on('finish', function() {
res.end(); // Send the response once ZIP is finished.
});
// Pipe the ZIP output to res:
zip.pipe(res);
// Add files to ZIP:
filesToZip.map((filename) => {
zip.append(new lazystream.Readable(() => fs
.createReadStream(filename), {
name: filename,
});
});
// Finalize the ZIP. Compression will start and output will
// be piped to res. Once ZIP is finished, res.end() will be
// called.
zip.finalize();
}
您可以围绕它进行构建,以缓存已构建的ZIP,而不是每次都在运行中即时构建它们,这既浪费时间和资源,对于大多数用例来说也不可取。