简体   繁体   English

使用跨浏览器兼容的 JavaScript 下载 PDF

[英]Downloading a PDF using JavaScript that is Cross Browser Compatible

I can download a PDF using AngularJS in Chrome, but this doesn't appear to work in the latest FireFox, Internet Explorer 11 or Edge (assuming it doesn't work for IE10 either), and I know a shim is needed for IE9 .我可以在 Chrome 中使用 AngularJS 下载 PDF,但这似乎不适用于最新的 FireFox、Internet Explorer 11 或 Edge(假设它也不适用于 IE10),而且我知道IE9 需要垫片 Don't know if this the best shim for this if anyone has an opinion, but currently it doesn't seem to work.如果有人有意见,不知道这是否是最好的垫片,但目前它似乎不起作用。 I tried it with a response type of blob and arraybuffer just in case that made a difference, and it doesn't.我用blobarraybuffer的响应类型尝试了它,以防万一,它没有。

All this counters what caniuse indicates about using the Blob URLs.所有这些都与caniuse指示的使用 Blob URL相悖 Anyone have this working in IE9 and up, and the last couple versions of FF, and can point out what I'm doing wrong?任何人都可以在 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);
});

UPDATE更新

Currently the best (only) answer works for IE10, 11, Edge, FF, and continues to work with Chrome.目前最好的(唯一的)答案适用于 IE10、11、Edge、FF,并继续与 Chrome 一起使用。 IE9 won't work using this solution if anyone has another polyfill/shim/other/etc, and Safari doesn't support the download attribute so the solution in the chosen answer doesn't work in an SPA since it just redirects the current page so in both these cases I've just left TODO stubs.如果有人有另一个 polyfill/shim/other/etc,IE9 将无法使用此解决方案,并且 Safari 不支持下载属性,因此所选答案中的解决方案在 SPA 中不起作用,因为它只是重定向当前页面所以在这两种情况下,我都只留下了 TODO 存根。

This is an update to the posted answer with more information added in comments for anyone to use or hopefully add to so IE9 and Safari work as expected:这是对已发布答案的更新,在评论中添加了更多信息供任何人使用或希望添加到 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...
            }
        }
    }

I've used this with success in both IE11 and Chrome:我在 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); 
    }
}

TRY this.尝试这个。 it checks the browser and save the file accordingly它检查浏览器并相应地保存文件

saveFile(response: any, fileName: string) {
    let browser = navigator.userAgent.toLowerCase();
        if(browser.indexOf('trident') == -1){
            let dataType = response.type;
            let binaryData = [];
            binaryData.push(response);
            let downloadLink = document.createElement('a');
            downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, { type: dataType }));
            downloadLink.setAttribute('download', fileName);
            document.body.appendChild(downloadLink);
            downloadLink.click();
        }
        else{
            window.navigator.msSaveBlob(response, fileName);
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM