如何在Safari中显示保存文件对话框?

时间:2016-04-06 07:40:08

标签: javascript angularjs html5 safari pdf-generation

我需要帮助。我有一个角度应用程序,并使用DocRaptor想要生成PDF并将其保存为文件。但我无法触发对话框以使用我在Stack Overflow上找到的任何方法在Safari中保存文件。这些方法在当前浏览器选项卡中打开文件,并在新选项卡中替换网站html或打开文件。没有人不能显示对话框。这里是我尝试使用的示例。环境MacOS - EL Capitan。 Safari 9.0.3

Solution#1

var content = 'file content for example';
var blob = new Blob([ content ], { type : 'text/plain' });
$scope.url = (window.URL || window.webkitURL).createObjectURL( blob );

示例jsfiddle。在当前选项卡中显示文件。替换网站。但适用于Chrome。

Solution#2

<a target="_self" href="mysite.com/uploads/ahlem.pdf" download="foo.pdf">

示例jsfiddle。在Safari中根本不起作用。适用于Chrome。

Solution#3

<a class="btn" ng-click="saveJSON()" ng-href="{{ url }}">Export to JSON</a>

$scope.saveJSON = function () {
            $scope.toJSON = '';
            $scope.toJSON = angular.toJson($scope.data);
            var blob = new Blob([$scope.toJSON], { type:"application/json;charset=utf-8;" });           
            var downloadLink = angular.element('<a></a>');
                        downloadLink.attr('href',window.URL.createObjectURL(blob));
                        downloadLink.attr('download', 'fileName.json');
            downloadLink[0].click();
        };

示例Code Snippet。显示文件内容而不是文档的html。

Solution#4

function download(text, name, type) {
  var a = document.getElementById("a");
  var file = new Blob([text], {type: type});
  a.href = URL.createObjectURL(file);
  a.download = name;
}

示例Code Snippet。用Safari中的文件内容替换文档。适用于Chrome。

类似Solution#5

function download(text, name, type) {
    var a = document.createElement("a");
    var file = new Blob([text], {type: type});
    a.href = URL.createObjectURL(file);
    a.download = name;
    a.click();
}

示例jsfiddle。在Safari中根本不起作用。适用于Chrome。

此外,我尝试使用以下库: FileSaver - 它在Safari中打开文件而不是文档。所以你应该点击Cmd + S. Example。 如果我们使用类型'pplication / octet-stream',文件名将是未知的,或者出现错误'无法加载资源:帧加载中断'。 Issue

第二个库Downloadify - 在Safari中根本不起作用。 Issue

Angular library nw-fileDialog - 而不是保存,因为它显示选择文件。 Issue

DocRaptor拥有自己的example和jQuery。 角度为jsfiddle的示例。它适用于Chrome,但在Safari示例中,SAMEORIGIN无法正常工作

  

拒绝在一个框架中显示“https://docraptor.com/docs”,因为它将“X-Frame-Options”设置为“SAMEORIGIN”。

但是如果我们在服务器上重现它并更改“https://docraptor.com/docs.pdf”上的网址,它就会工作,并在新标签中打开文件并自动下载文件,因此您无法选择文件夹,下载后用户会看到白色的空屏幕标签浏览器。如果我们指定form target =“_ self”它将完美,但控制台将出现错误'无法加载资源:'。

对于这个问题,我将不胜感激。 谢谢。 问候。

2 个答案:

答案 0 :(得分:2)

尝试使用Blob文件:

// Buffer can be response from XMLHttpRequest/Ajax or your custom Int32 data
function download(buffer, filename) {
  var file = new Blob([buffer], {
    type: 'application/octet-stream' // Replace your mimeType if known
  });
  var fileReader = new FileReader();

  fileReader.onloadend = function(e) {
    var converted = e.target.result;
    converted.name = filename;
    converted.webkitRelativePath = filename;

    var iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
    iframe.src = converted;
  };
  fileReader.onerror = function(e) {
    throw new Error('Something is wrong with buffer data');
  };
  fileReader.file = file;
  fileReader.readAsDataURL(file);
}

它基本上使用filebuffer并将其下载为iframe内容。确保挂钩正确的mime类型,以便safari安全系统收到分析文件类型。

答案 1 :(得分:1)

理想情况下,解决方案#2将是答案,但下载属性为does not yet have cross-browser support

因此您必须使用<form>来创建下载。正如您所指出的,DocRaptor的jQuery example使用了这种技术。

SAMEORIGIN错误实际上是因为JSFiddle使用其原始设置在iFrame中运行代码。如果你直接从Angular应用程序运行,你就不会有任何问题。