使用AngularJS从Node.JS服务器下载文件

使用AngularJS从Node.JS服务器下载文件,angularjs,node.js,download,binary,Angularjs,Node.js,Download,Binary,我想用浏览器从运行NodeJS的服务器下载文件。 在服务器端,要提供文件,我有: exports.download = function(req, res) { var filename = "33.jpg"; var filePath = path.join(__dirname, '..', '..', 'downloads', filename); var stat = fs.statSync(filePath); var fileToSend = fs.readFileS

我想用浏览器从运行NodeJS的服务器下载文件。 在服务器端,要提供文件,我有:

exports.download = function(req, res) {
  var filename = "33.jpg";
  var filePath = path.join(__dirname, '..', '..', 'downloads', filename);
  var stat = fs.statSync(filePath);

  var fileToSend = fs.readFileSync(filePath);

  res.writeHead(200, {
      'Content-Type': 'image/jpeg',
      'Content-Length': stat.size,
      'Content-Disposition': filename
  });
  res.end(fileToSend);
};
名为33.jpg的文件存在,大小为744Kb。客户的电话效果很好

在AngularJS的客户端,我调用post调用来获取文件(当前未使用参数uri):

标题正常(我可以检索文件名)

我的问题是,文件已下载,但大小为1.5Mb,无法读取。我尝试了不同的方法处理流、将数据附加到响应、管道等,但没有成功。 另一点(不确定是否重要):在Safari中打开文件时会显示一个断开的图标,而在Chrome中则会保存文件

PS:如果信息有用的话,我和约曼一起创建了这个项目

谢谢大家

[更新] 新版本的服务器功能(仍不工作)

[更新2]
双倍大小的文件在文件中随机包含额外的“efbffd”字符序列,使其无法读取

您正在使用
res#end
而不是
res#send
(带S)发送响应的头部,而不是正文


从for
res#end

用于在没有任何数据的情况下快速结束响应如果需要使用数据进行响应,请使用res.send()和res.json()等方法。


将响应类型的定义设置为blob解决了此问题

  $http({
      url: '/api/files/download',
      method: "POST",
      data: {
        uri: uri
      },
      responseType: 'blob'
  }).then(function (response) {
      var data = response.data;
      var headers = response.headers;
      var blob = new Blob([data], { type: 'audio/mpeg' });
      var fileName = headers('content-disposition');
      saveAs(blob, fileName);
  }).catch(function (response) {
    console.log('Unable to download the file')
  });

谢谢我更正了(也是设置标题部分),但结果是一样的:收到的文件大小是原始文件的两倍,浏览器(和os)
res.write(fileToSend)无法读取;res.end()相同的结果。我想问题更多地来自Angular方法,而不是Node.JS端……错误:我的控制台中没有定义saveAs。如何解决安装模块角度文件保护程序并将SaveAs factory作为控制器的参数
exports.download = function(req, res) {
  var filename = "33.jpg";
  var filePath = path.join(__dirname, '..', '..', 'downloads', filename);
  var stat = fs.statSync(filePath);
  var fileToSend = fs.readFileSync(filePath);
  res.set('Content-Type', 'image/jpeg');
  res.set('Content-Length', stat.size);
  res.set('Content-Disposition', filename);
  res.send(fileToSend);
};
exports.download = function(req, res) {
    // ...
    res.send(fileToSend);
};
  $http({
      url: '/api/files/download',
      method: "POST",
      data: {
        uri: uri
      },
      responseType: 'blob'
  }).then(function (response) {
      var data = response.data;
      var headers = response.headers;
      var blob = new Blob([data], { type: 'audio/mpeg' });
      var fileName = headers('content-disposition');
      saveAs(blob, fileName);
  }).catch(function (response) {
    console.log('Unable to download the file')
  });