使用blob内容作为文件在浏览器中生成“保存文件”对话框

时间:2017-03-25 15:10:06

标签: javascript node.js express

我想在点击按钮时将HTML画布导出为图像。到目前为止,我的方法是将按钮包装在一个锚点和onclick中,通过将content-disposition设置为attachment来为响应发送请求到我的API以生成另存为对话框。老实说,我并不是真的需要也不想去我的服务器端API,因为画布在我的客户端代码中,但我知道生成一个'保存文件的唯一方法'对话框是通过将响应标题的内容配置设置为附件。示例here建议使用FileSaver.js中的saveAs()但我们的教授不允许我们使用任何外部库。有没有办法生成'保存文件'前端代码中的对话框与使用纯JS的saveAs()类似。如果没有,那么用我的请求发送canvas 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();
}

BACKEND:

        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");}
  });

1 个答案:

答案 0 :(得分:0)

您可以创建

<a> 
通过将Blob传递给

,将href属性设置为Blob URL的

元素

URL.createObjectURL()

download 

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

<a> 
要记录的

元素,请调用

.click()

在元素上。

另见How to download a file without using <a> element with download attribute or a server?