2015-09-07 2 views
5

Ich möchte Dateien mit meinem Browser von meinem Server mit NodeJS herunterladen. Auf der Serverseite, die Datei muss ich dienen:Laden Sie eine Datei von Node.JS Server mit AngularJS herunter

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

Die Datei mit dem Namen 33.jpg existiert und Größe 744Kb. Der Anruf vom Client funktioniert super

Auf der Clientseite mit AngularJS hier, wie ich einen Beitrag Aufruf rufen Sie die Datei zu erhalten (zur Zeit der Parameter uri nicht verwendet wird):

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

Die Header sind ok (Ich kann den Dateinamen abrufen)

Mein Problem ist, dass eine Datei heruntergeladen wird, aber mit einer Größe von 1,5 MB und ist nicht lesbar. Ich habe verschiedene Methoden mit Streams ausprobiert, Daten an Response, Pipe usw. ohne Erfolg angehängt. Ein weiterer Punkt (nicht sicher ist wichtig): innerhalb von Safari der Dateien mit einem gebrochenen Symbol geöffnet werden angezeigt, in Chrome die Datei

PS gespeichert wird: i erstellt das Projekt mit Yeoman, wenn die Informationen nützlich ist

Dank alle

[Update] Neue Version der Server-Funktion (noch nicht funktioniert)

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

[Update 2] Die doppelte Größe Datei enthält extra „efbffd“ char-Sequenz zufällig in der Datei unlesbar

+0

'res.write (fileToSend) blob; res .end(); ' – AdityaParab

+0

Gleiches Ergebnis. Ich denke, das Problem kommt von der Angular-Methode mehr als die Node.JS Seite ... –

Antwort

6

Problem mit einer Definition des Antworttyp gelöst gesetzt

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

Fehler: saveAs ist nicht in meiner Konsole definiert. So lösen Sie –

+1

Installieren Sie das Modul Angular-File-Saver und setzen Sie SaveAs Factory als Parameter auf Ihren Controller –

0
machen

Sie den Kopf der Antwort senden, aber der Körper nicht durch res#end statt res#send (mit einem mit S).

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

Vom Express documentation für res#end:

Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() and res.json().

+0

Danke. Ich korrigierte (auch die Header-Teil), aber das Ergebnis ist das gleiche: eine empfangene Datei doppelte Größe als das Original und nicht lesbar durch den Browser (und os) –