Descargue un archivo del servidor Node.JS con AngularJS

Me gustaría descargar archivos con mi navegador desde mi servidor que funciona con NodeJS. En el lado del servidor, para servir el archivo tengo:

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

El archivo llamado 33.jpg existe y tiene un tamaño de 744Kb. La llamada del cliente funciona muy bien.

En el lado del cliente con AngularJS aquí es cómo llamo a una llamada posterior para obtener el archivo (actualmente no se usa el parámetro uri):

 $scope.downloadTrack = function(uri) { $http.post('/api/files/download', {uri: uri}).then(function(response) { var blob = new Blob([response.data], { type: 'image/jpeg' }); var fileName = response.headers('content-disposition'); saveAs(blob, fileName); }, function(response) { console.log('Download error'); console.log(response); }); } 

Los encabezados están bien (puedo recuperar el nombre del archivo)

Mi problema es que un archivo se descarga pero con un tamaño de 1.5Mb y es ilegible. Probé diferentes métodos con secuencias, agregue datos a la respuesta, tuberías, etc. sin éxito. Otro punto (no estoy seguro es importante): en Safari, los archivos se abren con un icono roto, en Chrome se guarda el archivo

PD: creé el proyecto con Yeoman si la información es útil

Gracias a todos

[Actualización] Nueva versión de la función del servidor (aún no funciona)

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

[Actualización 2] El archivo de tamaño doble contiene una secuencia de caracteres extra “efbffd” aleatoriamente en el archivo que lo hace ilegible

Problema resuelto con una definición del tipo de respuesta establecido en 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') }); 

Está enviando el encabezado de la respuesta pero no el cuerpo utilizando res#end lugar de res#send (con una S).

 exports.download = function(req, res) { // ... res.send(fileToSend); }; 

De la documentación Express para res#end :

Se usa para finalizar rápidamente la respuesta sin ningún dato. Si necesita responder con datos, use métodos como res.send () y res.json ().