2015-09-07 18 views
5

Chciałbym pobrać pliki z moją przeglądarką z mojego serwera działającego z NodeJS. Po stronie serwera, aby służyć plik mam:Pobierz plik z serwera Node.JS z AngularJS

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

Plik nazywa 33.jpg istnieje i jest 744Kb wielkości. Rozmowa z klientem działa świetnie

Po stronie klienta z angularjs Oto jak zadzwonić wywołanie POST pobrać plik (obecnie uri parametr nie jest używany):

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

Nagłówki są ok (mogę pobrać nazwę pliku)

Mój problem polega na tym, że plik został pobrany, ale ma rozmiar 1,5 MB i jest nieczytelny. Próbowałem różnych metod ze strumieniami, dołączałem dane do odpowiedzi, potoku itp. Bez powodzenia. Kolejnym punktem (nie wiem, jest bardzo ważne): w ciągu Safari pliki są otwarte ze złamanym ikony wyświetlane w ciągu Chrome plik jest zapisywany

PS: I stworzył projekt z Yeoman jeżeli informacja jest przydatna

Dzięki wszystko

[Aktualizacja] Nowa wersja funkcji serwera (jeszcze nie działa)

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

[Aktualizacja 2] Plik podwójnej wielkości zawiera dodatkowy „efbffd” sekwencję char losowo w pliku co nieczytelny

+0

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

+0

Ten sam wynik. Wydaje mi się, że problem pochodzi z metody Angulara bardziej niż strona Node.JS ... –

Odpowiedz

6

problem rozwiązany w definicji rodzaju reakcji ustawiony blob

$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

Błąd: saveAs nie jest zdefiniowany w mojej konsoli. jak rozwiązać –

+1

zainstalować moduł kątowy-wygaszacz i umieścić fabrycznie SaveAs jako parametr do kontrolera –

0

Wysyłasz głowę odpowiedzi, ale nie ciała za pomocą res#end zamiast res#send (ze związkiem S).

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

Z Express documentation do 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

Dzięki. Poprawiłem (również część zestawów nagłówków), ale wynik jest taki sam: odebrany plik dwukrotnie większy niż oryginał i nieczytelny przez przeglądarkę (i os). –