我可以在Chrome中使用AngularJS下载PDF,但这在最新的FireFox、Internet Explorer 11或Edge中似乎不起作用(假设它也不适用于IE10),我知道IE9需要一个填充程序。如果有人有意见的话,不知道这是否是最好的垫片,但目前它似乎不起作用。我尝试了blob
和arraybuffer
的响应类型,以防产生影响,但没有。
所有这些都与canius关于使用Blob URL的指示相反。有人在IE9及以上版本,以及FF的最后几个版本中使用过这个,并且可以指出我做错了什么吗?
$http({
url: '/api/v1/download',
method: 'GET',
responseType: 'blob' // or 'arraybuffer'
}).then(function (response) {
// Use the Blob object to create an object URL to download the file
var url = URL.createObjectURL(response.data);
// var url = URL.createObjectURL(new Blob([response], {type: 'application/pdf'})); // arraybuffer version
// Create an anchor to perform download, but don't append to the DOM
anchor.href = downloadUrl;
anchor.download = filename;
anchor.target = '_blank';
anchor.click();
URL.revokeObjectURL(downloadUrl);
anchor = null;
}).catch(function (reason) {
console.log('FAIL', reason);
});
更新
目前,最好的(唯一的)答案适用于IE10、11、Edge、FF,并继续适用于Chrome。如果有人有另一个polyfill/shim/other/etc,IE9将无法使用此解决方案,并且Safari不支持下载属性,因此所选答案中的解决方案在SPA中不起作用,因为它只是重定向当前页面,所以在这两种情况下,我都只留下了TODO存根。
这是对发布答案的更新,在评论中添加了更多信息,供任何人使用或希望添加到其中,以便IE9和Safari按预期工作:
function performDownload(blob, filename) {
// IE9 has no API for handling downloads using Blob objects, and doesn't support the download attribute
if(isIE() == 9) {
// TODO: polyfill/shim/other... change response type to?
}
// Only works for IE10 and up, including Edge
else if (typeof window.navigator.msSaveBlob !== 'undefined') {
// Provides a prompt to save the file to a location of users choice
window.navigator.msSaveBlob(blob, filename);
}
// Browsers that adhere to current standards can implement downloads
// using the Blob object with the download anchor attribute
// ---
// NOTE: Edge 13+ is compliant with both these standards, but Edge 12
// does not support the download anchor attribute so all versions
// have been grouped to use the propriety `msSaveBlob` method
else {
// Use the Blob object to create an object URL to download the file
var URL = window.URL;
var downloadUrl = URL.createObjectURL(blob);
var anchor = document.createElement('a');
if(angular.isDefined(anchor.download)) {
anchor.href = downloadUrl;
anchor.download = filename;
anchor.target = '_blank';
document.body.appendChild(anchor); // Required by Firefox
anchor.click();
// Release the existing object URL, and the anchor
$timeout(function () {
URL.revokeObjectURL(downloadUrl);
document.body.removeChild(anchor);
anchor = null;
}, 100);
}
else {
// TODO: Safari does not support the download anchor attribute...
}
}
}
我在IE11和Chrome中都成功地使用了这个:
function saveBlob(response, contentType, filename) {
let blob = new Blob([response.arrayBuffer()], { type: contentType });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround
window.navigator.msSaveBlob(blob, filename);
} else {
let URL = window.URL;
let downloadUrl = URL.createObjectURL(blob);
if (filename) {
let a = document.createElement('a');
if (typeof a.download === 'undefined') {
window.location.href = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location.href = downloadUrl;
}
// cleanup
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100);
}
}