Dukungan untuk mengunduh file biner dalam menggunakan ajax tidak bagus, masih banyak yang sedang dikembangkan sebagai draft yang masih berfungsi .
Metode pengunduhan sederhana:
Anda dapat meminta browser mengunduh file yang diminta hanya dengan menggunakan kode di bawah ini, dan ini didukung di semua browser, dan jelas akan memicu permintaan WebApi sama saja.
$scope.downloadFile = function(downloadPath) {
window.open(downloadPath, '_blank', '');
}
Metode pengunduhan biner Ajax:
Menggunakan ajax untuk mengunduh file biner dapat dilakukan di beberapa browser dan di bawah ini merupakan implementasi yang akan bekerja dalam rasa terbaru Chrome, Internet Explorer, FireFox dan Safari.
Ini menggunakan arraybuffer
jenis respons, yang kemudian dikonversi menjadi JavaScript blob
, yang kemudian disajikan untuk menyimpan menggunakan saveBlob
metode - meskipun ini hanya saat ini ada di Internet Explorer - atau berubah menjadi gumpalan data URL yang dibuka oleh browser, memicu dialog unduhan jika tipe mime didukung untuk dilihat di browser.
Dukungan Internet Explorer 11 (Tetap)
Catatan: Internet Explorer 11 tidak suka menggunakan msSaveBlob
fungsi jika telah alias - mungkin fitur keamanan, tetapi lebih cenderung cacat, Jadi menggunakan var saveBlob = navigator.msSaveBlob || navigator.webkitSaveBlob ... etc.
untuk menentukan saveBlob
dukungan yang tersedia menyebabkan pengecualian; karenanya mengapa kode di bawah sekarang menguji secara navigator.msSaveBlob
terpisah. Terima kasih? 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;
});
};
Pemakaian:
var downloadPath = "/files/instructions.pdf";
$scope.downloadFile(downloadPath);
Catatan:
Anda harus memodifikasi metode WebApi Anda untuk mengembalikan header berikut:
Saya telah menggunakan x-filename
header untuk mengirim nama file. Ini adalah tajuk khusus untuk kenyamanan, namun Anda dapat mengekstrak nama file dari content-disposition
tajuk menggunakan ekspresi reguler.
Anda juga harus mengatur content-type
header mime untuk respons Anda, sehingga browser mengetahui format data.
Saya harap ini membantu.