HTML IFrame 不允许下载文件

Gre*_*byn 3 html javascript jquery velo

我正在尝试下载一个根据其接收的值自行构建的文件。这是我的代码

\n
<html>\n<head>\n<script>\n    var myList=[];\n    window.onmessage = function(event){\n    if (event.data) {\n      myList = event.data;\n      if (myList.length>0) {\n        buildHtmlTable();\n      }\n    }\n    else {\n      myList = [];\n    }\n  };\n function buildHtmlTable() {\n     var columns = addAllColumnHeaders(myList);\n \n     for (var i = 0 ; i < myList.length ; i++) {\n         var row$ = $(\'<tr/>\');\n         for (var colIndex = 0 ; colIndex < columns.length ; colIndex++) {\n             var cellValue = myList[i][columns[colIndex]];\n \n             if (cellValue == null) { cellValue = ""; }\n \n             row$.append($(\'<td/>\').html(cellValue));\n         }\n         $("#excelDataTable").append(row$);\n         \n     }\n     return exportF(); // Make Excel file download now\n }\n function addAllColumnHeaders(myList)\n {\n     var columnSet = [];\n     var headerTr$ = $(\'<tr/>\');\n \n     for (var i = 0 ; i < myList.length ; i++) {\n         var rowHash =`enter code here` myList[i];\n         for (var key in rowHash) {\n             if ($.inArray(key, columnSet) == -1){\n                 columnSet.push(key);\n                 headerTr$.append($(\'<th/>\').html(key));\n             }\n         }\n     }\n     $("#excelDataTable").append(headerTr$);\n \n     return columnSet;\n }\n function exportF() {\n  var table = document.getElementById("excelDataTable");\n  var html = table.outerHTML;\n\n  var url = \'data:application/vnd.ms-excel,\' + escape(html);\n  var link = document.getElementById("downloadLink");\n  link.setAttribute("href", url);\n  link.setAttribute("download", "export.xls"); // Choose the file name here\n  link.click(); // Download your excel file   \n  return false;\n}\n </script>\n</head>\n<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>\n\n<body onLoad="">\n    <table id="excelDataTable" border="1">\n     </table>\n     <a style="display: none" id="downloadLink"></a>\n</body>\n\n</html>\n
Run Code Online (Sandbox Code Playgroud)\n

代码本身可以工作,但我得到的错误是“不允许下载。启动或实例化下载的框架已沙箱化,但未设置标志 \xe2\x80\x98allow-downloads\xe2\x80\x99。请参阅 https : //www.chromestatus.com/feature/5706745674465280了解更多详细信息。”

\n

我可以做什么来解决这个问题?感觉我已经尝试了所有我能得到的东西,但似乎没有任何东西可以下载

\n

Kai*_*ido 7

正如警告消息所示,如果没有权限,您将无法从沙盒 iframe 初始化下载allow-downloads

所有解决方案都意味着有权访问显示 iframe 的页面(以下简称“嵌入器”)。

最简单且推荐的方法,

是要求嵌入者在定义 iframe 时添加此权限:

<iframe src="yourpage.html" sandbox="allow-scripts allow-downloads"></iframe>
Run Code Online (Sandbox Code Playgroud)

另一种方法是要求他们根本不要对该 iframe 进行沙箱处理,

<iframe src="yourpage.html"></iframe>
Run Code Online (Sandbox Code Playgroud)

但我想如果他们这样做了,那是因为他们不够信任你的页面。


最后,更复杂的方法是将生成的文件传递回父窗口。

为此,您需要与您的客户一起定义一个新的 API。
显然,您可以向他们发出一个全局message事件,但我想最干净的方法是让他们将MessageChannel的 MessagePort 与myList数据一起传递,这样他们就可以轻松地等待响应,并确保他们只会捕获响应并且没有其他不相关的消息。

所以在嵌入器页面中他们会这样做

frame.onload = (evt) => {
  const channel = new MessageChannel();
  // handle the response from the iframe
  channel.port2.onmessage = (evt) => {
    const file = evt.data;
    saveAs( file, "file.html" ); // the embedder is reponsible to initialize the download
  };
  frame.contentWindow.postMessage( embedders_data, [ channel.port1 ] );
};
Run Code Online (Sandbox Code Playgroud)

在你的页面中你会做

window.onmessage = (evt) => {
  const myList = evt.data;
  // get the MessageChannel's port out of the transfer-list
  const port = evt.ports[ 0 ];
  // buildHtmlTable has to return the final file, not to make it download
  const file = buildHtmlTable( myList );
  if( port ) { 
    port.postMessage( file ); // send back to embedder
  }
};
Run Code Online (Sandbox Code Playgroud)

将其视为实时 plnkr

Ps:请注意,您的文件不是 xlsx 文件,而是 HTML 标记。