【问题标题】:Chrome blocks a Blob object when downloading as PDF下载为 PDF 时,Chrome 会阻止 Blob 对象
【发布时间】:2016-08-03 12:12:23
【问题描述】:

我创建了一小段脚本,它调用 API 来获取 PDF 并将 responseType 作为数组缓冲区发送。

我使用它创建了一个新的 Blob 并将类型设置为 'application/pdf'

为了强制下载,我创建了一个锚元素,将 blob 传递给它并单击它。

这在本地和我的测试服务器上的其他浏览器上运行良好,但在 Chrome 上我失败了 - 下载栏中没有文件。

PDF 绝对可用,因为我可以将 API 的 URL 粘贴到选项卡中并查看它,并将原始 API 调用的响应传递给 Blob。

示例代码

var fileName = 'dummyFilename-' + offerId + '.pdf';
var blob = new window.Blob([resData], { type: 'application/pdf' });

var anchorElement = document.createElement('a');
var url = window.URL.createObjectURL(blob);

document.body.appendChild(anchorElement);
anchorElement.id = 'anchorElement';
anchorElement.hidden = 'true';
anchorElement.href = url;

if (typeof anchorElement.download !== 'undefined') {
    anchorElement.download = fileName;
} else {
    anchorElement.target = '_blank';
}

anchorElement.click();

【问题讨论】:

    标签: javascript google-chrome pdf blob


    【解决方案1】:

    你有像 uBlock Origin 这样的广告拦截器扩展吗?如果是这样,它可能会阻止弹出窗口/选项卡中的所有 blob URL。 Easylist 默认是这样做的:

    https://github.com/easylist/easylist/commit/e3276b6ff9611e821d0e8ba7ac4dc336a4e3b765

    在我的例子中,我为我的网站禁用了 uBlock Origin 并且它起作用了。

    【讨论】:

    • 帮我修好了!
    【解决方案2】:

    强制这样做总是有点老套...:

    如果您单击以执行该功能的 HTML 元素是一个链接,您可能需要尝试添加一个 download 属性:

    <a href="path/to/your/file.pdf" download>Download PDF</a>
    

    如果你愿意,你可以重命名它:

    <a href="path/to/your/file.pdf" download="downloaded-pdf-name.pdf">Download PDF</a>
    

    如果您使用该解决方案使其在其他浏览器中工作,其中 download 属性将不起作用,您的点击事件处理程序应如下所示:

    document.getElementById('#download-pdf').onclick = function (event) {
        if (!"download" in document.createElement("a")) {
            // Download is NOT supported, the browser is probably not Chrome
            // You don't want the native behaviour, which will probably open
            // the PDF in another tab, so:
            event.preventDefault();
    
            // TODO: Adapt your code to execute from here...
        }
    }
    

    但是,download 检查在 Firefox 中可能不起作用。在此处查看答案中的 cmets:How to detect support for the HTML5 "download" attribute?

    如果您有该选项,建议您在 HTTP 响应标头中设置 Content-Disposition = 'attachment; filename=downloaded-pdf-name.pdf'。查看here 了解在不同后端执行此操作的具体方法。

    【讨论】:

    • 其实我发现我真的只需要Blob就可以让PDF在IE中下载。最后,我只是将点击指向一个设置了下载属性的普通 URL,以通过为不支持此功能的浏览器打开一个新选项卡来强制执行此操作。我仍然不确定为什么 Chrome 没有正确处理 Blob。
    【解决方案3】:

    你试过了吗? (不创建元素)...我希望它有所帮助

    var fileName = 'dummyFilename-' + offerId + '.pdf';
    var blob = new window.Blob([resData], { type: 'application/pdf' });
    // Parse blob object to base64 to prevent chrome blocking:
    var reader = new FileReader();
    reader.readAsDataURL(blob); 
    reader.onloadend = function() {
        base64data = reader.result;
        // For IE:
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveOrOpenBlob(base64data);  
        } // For webkit
        else {
            var objectUrl = URL.createObjectURL(base64data);
            window.open(objectUrl);  
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-17
      • 1970-01-01
      • 2018-08-26
      • 2019-04-02
      • 2022-01-22
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多