Die Unterstützung für das Herunterladen von Binärdateien mit Ajax ist nicht großartig, sie wird derzeit noch als Arbeitsentwurf entwickelt .
Einfache Download-Methode:
Sie können den Browser die angeforderte Datei einfach mithilfe des folgenden Codes herunterladen lassen. Dies wird in allen Browsern unterstützt und löst die WebApi-Anforderung offensichtlich trotzdem aus.
$scope.downloadFile = function(downloadPath) {
window.open(downloadPath, '_blank', '');
}
Ajax binäre Download-Methode:
Die Verwendung von Ajax zum Herunterladen der Binärdatei kann in einigen Browsern erfolgen. Im Folgenden finden Sie eine Implementierung, die in den neuesten Versionen von Chrome, Internet Explorer, FireFox und Safari funktioniert.
Es wird ein arraybuffer
Antworttyp verwendet, der dann in ein JavaScript konvertiert wird blob
, das dann entweder zum Speichern mithilfe der saveBlob
Methode angezeigt wird - obwohl dies derzeit nur in Internet Explorer vorhanden ist - oder in eine Blob-Daten-URL umgewandelt wird, die vom Browser geöffnet und ausgelöst wird Der Download-Dialog, wenn der MIME-Typ für die Anzeige im Browser unterstützt wird.
Internet Explorer 11-Unterstützung (behoben)
Hinweis: Internet Explorer 11 mochte die Verwendung der msSaveBlob
Funktion nicht, wenn sie mit einem Alias versehen war - möglicherweise eine Sicherheitsfunktion, aber eher ein Fehler. Die Verwendung var saveBlob = navigator.msSaveBlob || navigator.webkitSaveBlob ... etc.
zur Ermittlung der verfügbaren saveBlob
Unterstützung verursachte also eine Ausnahme. Daher wird der folgende Code jetzt navigator.msSaveBlob
separat getestet . Vielen Dank? Microsoft
// Based on an implementation here: web.student.tuwien.ac.at/~e0427417/jsdownload.html
$scope.downloadFile = function(httpPath) {
// Use an arraybuffer
$http.get(httpPath, { responseType: 'arraybuffer' })
.success( function(data, status, headers) {
var octetStreamMime = 'application/octet-stream';
var success = false;
// Get the headers
headers = headers();
// Get the filename from the x-filename header or default to "download.bin"
var filename = headers['x-filename'] || 'download.bin';
// Determine the content type from the header or default to "application/octet-stream"
var contentType = headers['content-type'] || octetStreamMime;
try
{
// Try using msSaveBlob if supported
console.log("Trying saveBlob method ...");
var blob = new Blob([data], { type: contentType });
if(navigator.msSaveBlob)
navigator.msSaveBlob(blob, filename);
else {
// Try using other saveBlob implementations, if available
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)
{
// Get the blob url creator
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
if(urlCreator)
{
// Try to use a download link
var link = document.createElement('a');
if('download' in link)
{
// Try to simulate a click
try
{
// Prepare a blob URL
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);
// Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
link.setAttribute("download", filename);
// Simulate clicking the download link
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)
{
// Fallback to window.location method
try
{
// Prepare a blob URL
// Use application/octet-stream when using window.location to force download
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)
{
// Fallback to window.open method
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);
// Optionally write the error out to scope
$scope.errorDetails = "Request failed with status: " + status;
});
};
Verwendung:
var downloadPath = "/files/instructions.pdf";
$scope.downloadFile(downloadPath);
Anmerkungen:
Sie sollten Ihre WebApi-Methode ändern, um die folgenden Header zurückzugeben:
Ich habe den x-filename
Header verwendet, um den Dateinamen zu senden. Dies ist der Einfachheit halber ein benutzerdefinierter Header. Sie können den Dateinamen jedoch content-disposition
mit regulären Ausdrücken aus dem Header extrahieren .
Sie sollten den content-type
MIME-Header auch für Ihre Antwort festlegen , damit der Browser das Datenformat kennt.
Ich hoffe das hilft.