2017-10-18 186 views
2

我有一个服务可以构建一个csv文件并将其返回给用户。目前使用expressjs v4.14,nodejs v8.7.0。我的问题是,当我调用服务为它创建一个大的csv文件时,由于chrome中的“网络错误”而导致下载失败。对于较小的文件,该服务工作正常。我也可以浏览到/temp/文件夹,并且存在整个预期文件。在每一件'我试过的东西'中,我都可以下载较小的文件,但不能下载较大的文件。无法在nodejs中下载大文件

服务:

download.post('/csv', (req, res, next) => { 

     res.status(200).header('Content-Type', 'text/csv'); 
     const newUUID = uuid.v1(); 

     let ws: WriteStream = fs.createWriteStream(`${__dirname}/../../temp/${newUUID}.csv`); 

     ws.on('finish',() => { 
      res.download(`${__dirname}/../../temp/${newUUID}.csv`); 
     }); 

     //csv file built here 
     ws.write('huge stuff easily 50k rows and 10 mb file'); 
     ws.end(); 
}); 

Chrome的错误:

Chrome的网络标签和开发者控制台不给我发生了什么事的任何指示。这下载弹出是我得到的。为了以防万一,我清除了Cookie /缓存中的所有内容,并没有帮助。

enter image description here

事情我想:直接

  • 写入块,以响应流。
  • 使用可读流https://nodejs.org/api/stream.html#stream_readable_streams,将字符串转换为字节并管道它。
  • 创建本地文件(writestream)后结束writestream创建本地文件流媒体回来(readstream管排入水库)
  • res.download(文件)

更新:

端试图从邮递员服务,它的工作,所以我认为这是一个angularjs问题。

Angularjs

$http({ 
      cache: false, 
      url: "/download/csv", 
      headers: { 
       'accept': 'text/csv' 
      }, 
      method: 'POST', 
      data: { 
       rows: rows, 
       title: title ? title : '' 
      } 
     }).success(function (data, status, headers, config) { 
     var anchor = angular.element('<a/>'); 
     anchor.attr({ 
      href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data), 
      target: '_blank', 
      download: 'csv_info.csv' 
     })[0].click(); 
    }).error(function (data, status, headers, config) { 

    }); 

回答

0

原来是从在angularjs创建的锚定标记href属性的限制。这使用FileSaver解决:

$http({ 
     cache: false, 
     url: "/download/csv", 
     headers: { 
      'accept': 'text/csv' 
     }, 
     method: 'POST', 
     data: { 
      rows: rows, 
      title: title ? title : '' 
     } 
    }).success(function (data, status, headers, config) { 
      var file = new File([data], "info.csv", {type: "text/csv;charset=utf-8"}); 
      saveAs(file); 
}).error(function (data, status, headers, config) { 

});