使用 Blob 内容作为文件,在浏览器中生成"保存文件"对话框



我想在单击按钮时将HTML画布导出为图像。到目前为止,我的方法是将按钮包装在锚点中并单击,通过设置响应attachmentcontent-disposition向我的 API 发送请求以生成另存为对话框。老实说,我真的不需要也不想为此使用我的服务器端 API,因为画布在我的客户端代码中,但我知道生成"保存文件"对话框的唯一方法是将响应标头的内容处置设置为附件。这里的例子建议使用 FileSaver 中的saveAs().js但是我们的教授不允许我们使用任何外部库。有没有办法从前端代码生成"保存文件"对话框,类似于使用纯 JS() 的 saveAs()。如果没有,除了将画布 blob 与我的请求一起发送并将其打包到后端的图像中之外,还有什么最干净的替代方法?

谢谢

更新:

我设法让它达到能够使用各种资源下载图像文件的地步。现在的问题是我下载的文件已损坏,我不确定问题可能是什么。下面是一些代码:

前端:

editjs.downloadCanvas = function(fileBlob,filename){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE){
console.log(this.status);
if(this.status === 200){
var a = document.createElement('a');
document.getElementById('export_annotation').parentNode.appendChild(a);
console.log("created anchor - trying to trigger download");
a.href = "/export/pdfs/"+filename+"/canvases/page/"+filename+"-pg-"+pageNum;
a.click();
}
}
};
var formData = new FormData();
formData.append("file", fileBlob);
formData.append("name", filename+"-pg-"+pageNum);
var url = "/export/pdfs/"+filename+"/canvases/"+pageNum;
xhr.open("POST",url,true);
console.log("sending export data");
xhr.send(formData);
}

editjs.getContent = function(dataURL,filename,callback){
var req = new XMLHttpRequest;
req.open( 'GET', dataURL );
req.responseType = 'arraybuffer';
req.onload = function fileLoaded(e)
{
var mime = this.getResponseHeader('content-type');
callback(new Blob([this.response], {type:mime}),filename) ;
};
req.send();
}

后端:

app.post('/export/pdfs/:fname/canvases/:page',upload.single("file"), function(req,res){
console.log("Creating export file!");
console.log(req.body.name);
if (req.session.user){
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
if(err) res.status(500).end("Database error");
console.log("Connected to Database");
var tmp_file = {filename: req.body.name, file_path: req.file.path};
db.collection('canvases').save(tmp_file, function(err, record) {
if (err) res.status(500).end("Database error");
db.close();
return res.send();
});
});
console.log("exporting to:");
console.log(req.file.path);
}
else{return res.status(403).end("Forbidden");}
});


app.get('/export/pdfs/:fname/canvases/page/:storedfname', function(req,res){
if (req.session.user){
console.log("reading");
console.log(req.params.storedfname);
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
if(err) res.status(500).end("Database error");
db.collection('canvases').findOne({filename: req.params.storedfname}, function(err, record) {
if (err) res.status(500).end("Database error");
console.log(record);
if (record){
db.close();
console.log("record found");
res.setHeader('Content-type','image/png');
res.setHeader('Content-disposition', "attachment; filename=" +req.params.storedfname+".png");
fs.createReadStream(record.file_path).pipe(res);
}
});
});
}
else{return res.status(403).end("Forbidden");}
});

您可以创建一个

<a> 

元素,通过将 Blob 传递给

URL.createObjectURL()
download 

属性设置为建议的文件名;追加

<a> 

元素到文档,调用

.click()

在元素上。

另请参阅如何在不使用具有下载属性或服务器的元素的情况下下载文件?

最新更新