Obsługa pobierania plików binarnych przy użyciu Ajax nie jest świetna, jest nadal w fazie rozwoju jako robocze wersje robocze .
Prosta metoda pobierania:
Możesz poprosić przeglądarkę o pobranie żądanego pliku po prostu za pomocą poniższego kodu, a jest to obsługiwane we wszystkich przeglądarkach i oczywiście spowoduje to samo wywołanie żądania WebApi.
$scope.downloadFile = function(downloadPath) {
window.open(downloadPath, '_blank', '');
}
Metoda pobierania plików binarnych Ajax:
Korzystanie z AJAX do pobierania pliku binarnego można wykonać w niektórych przeglądarkach, a poniżej znajduje się implementacja, która będzie działać w najnowszych wersjach Chrome, Internet Explorer, FireFox i Safari.
Używa typu arraybuffer
odpowiedzi, który jest następnie konwertowany na JavaScript blob
, który jest następnie przedstawiany w celu zapisania przy użyciu saveBlob
metody - chociaż jest to obecnie tylko w przeglądarce Internet Explorer - lub zamieniany na adres URL danych typu blob, który jest otwierany przez przeglądarkę, wyzwalając okno dialogowe pobierania, jeśli typ MIME jest obsługiwany do przeglądania w przeglądarce.
Obsługa przeglądarki Internet Explorer 11 (stała)
Uwaga: Internet Explorer 11 nie lubił używać tej msSaveBlob
funkcji, jeśli była aliasowana - być może była to funkcja bezpieczeństwa, ale bardziej prawdopodobne jest luka, więc użycie var saveBlob = navigator.msSaveBlob || navigator.webkitSaveBlob ... etc.
do określenia dostępnej saveBlob
obsługi spowodowało wyjątek; stąd dlaczego poniższy kod testuje teraz navigator.msSaveBlob
oddzielnie. Dzięki? Microsoft
$scope.downloadFile = function(httpPath) {
$http.get(httpPath, { responseType: 'arraybuffer' })
.success( function(data, status, headers) {
var octetStreamMime = 'application/octet-stream';
var success = false;
headers = headers();
var filename = headers['x-filename'] || 'download.bin';
var contentType = headers['content-type'] || octetStreamMime;
try
{
console.log("Trying saveBlob method ...");
var blob = new Blob([data], { type: contentType });
if(navigator.msSaveBlob)
navigator.msSaveBlob(blob, filename);
else {
var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
if(saveBlob === undefined) throw "Not supported";
saveBlob(blob, filename);
}
console.log("saveBlob succeeded");
success = true;
} catch(ex)
{
console.log("saveBlob method failed with the following exception:");
console.log(ex);
}
if(!success)
{
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
if(urlCreator)
{
var link = document.createElement('a');
if('download' in link)
{
try
{
console.log("Trying download link method with simulated click ...");
var blob = new Blob([data], { type: contentType });
var url = urlCreator.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute("download", filename);
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
link.dispatchEvent(event);
console.log("Download link method with simulated click succeeded");
success = true;
} catch(ex) {
console.log("Download link method with simulated click failed with the following exception:");
console.log(ex);
}
}
if(!success)
{
try
{
console.log("Trying download link method with window.location ...");
var blob = new Blob([data], { type: octetStreamMime });
var url = urlCreator.createObjectURL(blob);
window.location = url;
console.log("Download link method with window.location succeeded");
success = true;
} catch(ex) {
console.log("Download link method with window.location failed with the following exception:");
console.log(ex);
}
}
}
}
if(!success)
{
console.log("No methods worked for saving the arraybuffer, using last resort window.open");
window.open(httpPath, '_blank', '');
}
})
.error(function(data, status) {
console.log("Request failed with status: " + status);
$scope.errorDetails = "Request failed with status: " + status;
});
};
Stosowanie:
var downloadPath = "/files/instructions.pdf";
$scope.downloadFile(downloadPath);
Uwagi:
Należy zmodyfikować metodę WebApi, aby zwracała następujące nagłówki:
Użyłem x-filename
nagłówka, aby wysłać nazwę pliku. Jest to niestandardowy nagłówek dla wygody, możesz jednak wyodrębnić nazwę pliku z content-disposition
nagłówka za pomocą wyrażeń regularnych.
Powinieneś także ustawić content-type
nagłówek MIME dla swojej odpowiedzi, aby przeglądarka znała format danych.
Mam nadzieję, że to pomoże.