Safari 12无法下载PDF blob

12

这段代码用于通过blob下载pdf文件。在macOS和iOS的Safari 12上除外,它可以在每个浏览器上正常工作。即使在Safari 11上也可以正常工作。当我第一次运行代码时,它可以正常工作,但之后每次都会给我“WebKitBlobResource error 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);
}


如果仍然遇到此问题,请查看此链接。https://stackoverflow.com/a/63040798/11579692 - Vazgen
2个回答

6

看起来是target = "_blank"没有起作用。我已经替换为_self,这显然解决了问题。当我遇到相同的问题时,我发现了这个。

如果有人知道为什么我们不能使用_blank,我很乐意听取意见。


鉴于此处只涉及blobURI受到"_blank"限制的情况(dataURI似乎可以正常工作),我认为它是更大限制的一部分,即即使是window.open(blobURI)也会被阻止。 - Kaiido
1
我也在尝试解决这个问题,但我的问题是当我使用a.target ='_self'时,Chrome不再使用download =""属性中定义的文件名来命名blob下载... - bmcminn

6

显然,这是一个Safari 12的问题有时会发生。 这不能通过target="_self"修复,这与不同的回归错误有关。

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

  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");
?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接