Safari 12无法下载PDF Blob

时间:2018-10-29 15:25:06

标签: javascript macos pdf safari blob

此代码用于通过Blob下载pdf。除了适用于macOS和iOS的Safari 12,它在所有浏览器上均可正常运行。甚至Safari 11也可以使用。当我第一次运行代码时,它可以正常工作,但是每次之后它都给我“ WebKitBlobResource错误1”

function downloadFileFromBlob(fileBlob, fileName) {
    if (/\bMSIE\b|\bTrident\b/.test($window.navigator.userAgent)) {
        $window.navigator.msSaveOrOpenBlob(fileBlob, fileName);
    } else {
        var fileURL = $window.URL.createObjectURL(fileBlob);
        createDownloadElementAndClick(fileURL, fileName);
    }
}

function createDownloadElementAndClick(fileURL, fileName) {
    var anchorElement = $window.document.createElement('a');
    anchorElement.href = fileURL;
    anchorElement.target = '_blank';
    anchorElement.download = fileName;
    var event = $window.document.createEvent("MouseEvents");
    event.initEvent("click", true, false);
    anchorElement.dispatchEvent(event);
}

2 个答案:

答案 0 :(得分:2)

似乎target = "_blank"无效。我已经用_self代替了它,显然可以解决问题。我遇到同样的问题时就发现了这一点。

如果有人对为什么我们不能使用_blank有一个想法,我很想听听。

答案 1 :(得分:0)

显然,这是{em>有时发生的Safari 12 bugtarget = "_self"并不固定,它与different regression bug有关。

在修复该错误之前,丑陋的解决方法是:

  1. 将Blob发送到远程保存文件的服务器。
  2. 下载远程文件。

JavaScript代码

   async createDownloadElementAndClick(blob, fileName) {
            let options = {
                method:"POST",
                body:blob
            };

            await fetch(`https://example.com/upload.php`, options);

            window.open(`https://example.com/download.php?${fileName}`, "_self");
    }

PHP代码

在upload.php中:

<?php    
// add any authentication code as necessary here


    // gets entire POST body
    $data = file_get_contents('php://input');

    $filename = "temp/download.pdf";
    // write the data out to the file
    $fp = fopen($filename, 'wb');

    fwrite($fp, $data);
    fclose($fp);
?>

在download.php中:

<?php
    ob_start();
    $file = $_SERVER["QUERY_STRING"];

    // This is the line that tells Safari to download the file instead of opening it
    header("Content-disposition: attachment; filename=$file");
    header("Content-type: application/pdf", false);
    readfile("temp/download.pdf");

    ob_flush();
    // This deletes the pdf so there is little chance of contaminating the next call
    unlink("temp/download.pdf");
?>