我有一个SailsJS后端,我生成一个zip文件,这是我的前端,Redux的React App所要求的。我使用Sagas进行异步呼叫,使用fetch进行请求。在后端,它尝试了类似的东西:
//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文件结束。有什么建议吗?
答案 0 :(得分:1)
您尝试过的选项存在各种问题:
res.attachment
只会设置Content-Type
和Content-Disposition
标题,但实际上不会发送任何内容。
您可以使用它来正确设置标题,但您也需要将ZIP文件传输到响应中。
res.sendfile
:在此之后你不应该致电.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,而不是每次都在运行它们,这是耗费时间和资源的,而且对于大多数用例来说都是不可取的。