【问题标题】:Server side route to download file下载文件的服务器端路由
【发布时间】:2017-06-05 20:45:43
【问题描述】:

我有一个用于下载文件的服务器端路由。这是从客户端按钮单击调用的,一切正常。但是,一旦该按钮被单击一次,它将无法再次工作,直到加载另一条路线并返回。如何编码,以便可以多次单击按钮并每次触发服务器端路由?

我的按钮代码如下所示...

'click #view_document_download': function (event, tmpl) {
   Router.go('/download_document/' + this._id);
}

我的服务器端路由看起来像这样......

Router.route('/download_document/:_id', function () {

  //Get the file record to download
  var file = files.findOne({_id: this.params._id});

  //Function to take a cfs file and return a base64 string
  var getBase64Data = function(file2, callback) {
    var readStream = file2.createReadStream();
    var buffer = [];
    readStream.on('data', function(chunk) {
      buffer.push(chunk);
    });
    readStream.on('error', function(err) {
      callback(err, null);
    });
    readStream.on('end', function() {
      callback(null, buffer.concat()[0].toString('base64'));
    });
  };

  //Wrap it to make it sync    
  var getBase64DataSync = Meteor.wrapAsync(getBase64Data);

  //Get the base64 string
  var base64str = getBase64DataSync(file);

  //Get the buffer from the string
  var buffer = new Buffer(base64str, 'base64');

  //Create the headers
  var headers = {
    'Content-type': file.original.type,
    'Content-Disposition': 'attachment; filename=' + file.original.name
  };

  this.response.writeHead(200, headers);
  this.response.end(buffer, 'binary');

}, { where: 'server' });

【问题讨论】:

    标签: meteor iron-router


    【解决方案1】:

    也许您应该只通过一种方法从您的服务器返回一个对象并将其形成为客户端的文件?如果可能的话..

    在客户端创建文件非常简单,此时您不必处理路由器。

         function outputFile(filename, data) {
            var blob = new Blob([data], {type: 'text/plain'}); // !note file type..
            if(window.navigator.msSaveOrOpenBlob) {
                window.navigator.msSaveBlob(blob, filename);
            }
            else{
                var elem = window.document.createElement('a');
                elem.href = window.URL.createObjectURL(blob);
                elem.download = filename;        
                document.body.appendChild(elem)
                elem.click();        
                document.body.removeChild(elem);
            }
         }
         
         function getContentAndOutputFile() {
           var content = document.getElementById('content').value;
    
           outputFile('file.txt', content);
         }
    <input id="content" value="test content"/>
    <button onClick="getContentAndOutputFile()">Create File</button>

    【讨论】:

    • 我可以做到这一点,但我在这个服务器端有一个可行的解决方案,这只是我每次都想重置的路线。我更想知道这是否可能。
    • 另外,我有兴趣了解您的解决方案对标准服务器端下载的性能影响?
    • 好吧,就性能而言,它很简单,您只需将文件下载一次到客户端。下次点击它只需要相同的文件,而不会给服务器带来压力
    【解决方案2】:

    使用 a 元素代替 js 的“点击”事件
    页面 html

    <a href="/download_document/{{_id}}" download="true" target="_blank"></a> 
    

    服务器中的页面 js

    Router.route("/download_document/:fileId", function(){
        var file = files.findOne({_id: this.params.fileId});
        var contentFile = //file text
        let headers = {
          'Content-Type': 'text/plain',
          'Content-Disposition': "attachment; filename=file.txt"
        };
        this.response.writeHead(200, headers);
        this.response.end(contentFile);
      },
      {where: "server", name: "download"}
    );
    

    【讨论】:

      猜你喜欢
      • 2018-02-05
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      • 2016-06-01
      • 2015-02-28
      • 2011-09-23
      • 2021-11-20
      • 2019-12-11
      相关资源
      最近更新 更多