jQuery 将 iframe 写入 XLS 导致 iPhone 上的沙箱访问冲突

Posted

技术标签:

【中文标题】jQuery 将 iframe 写入 XLS 导致 iPhone 上的沙箱访问冲突【英文标题】:jQuery writing iframe to XLS causes sandbox access violation on iPhone 【发布时间】:2017-10-26 17:00:49 【问题描述】:

我有一个附加到将 iframe 写入 DOM 的 jQuery 操作的按钮输入。 iframe 指向一个 php 脚本,该脚本组装一个 Excel 文件以进行强制下载。

此按钮在桌面硬件上运行良好,但最新版本的 iPhone 版 Mac OS X 导致此脚本向浏览器控制台抛出 javascript 错误,并且似乎无法将 iframe 插入 DOM。我在 ios v10.3.3 和 v11.0.1 上复制了错误。

iOS v10.3.3 抛出以下 Javascript 错误:

SecurityError(DOM 异常 18):沙盒访问冲突:阻止“https://www.[REDACTED].com”处的框架访问“https://www.[REDACTED].com”处的框架。被访问的框架是沙盒的,并且缺少“allow-same-origin”标志。在第 3 行的https://www.[REDACTED].com/path/jquery/jquery.min.js 中

iOS v11.0.1 抛出以下内容:

SecurityError (DOM Exception 18): Blocked a frame with origin “https://www.[REDACTED].com”来自访问具有原点的框架 “x-apple-ql-id://256b58b2-0821-4779-810b-5493faa49e07”。框架 请求访问具有“https”协议,被访问的帧 具有“https”协议。协议必须匹配。在 https://www.[REDACTED].com/modules/jquery/jquery.min.js 第 3 行

这是我正在使用的 Javascript。

var LOCAL = 
    execReport : function()
    
        // Get form inputs
        var t = $('select[name="t"] option:selected').val();
        var s = $('select[name="s"] option:selected').val();

        // Write the iframe into the DOM
        var iframe = $('<iframe></iframe>', 
            'src' : '/xls/observationsReport.php?gid=' + majGroup.gid + '&season=' + s + '&t=' + t,
            'id' : 'reportIframe',
            'width' : '1',
            'height' : '1',
            'frameborder' : '0',
            'scrolling' : 'no',
            'sandbox' : 'allow-same-origin'
        ).appendTo('body').on('load', function() 
            // Wait for the iframe to finish loading
            var response = $.parseJSON($('#reportIframe').contents().find('body').html());

            // Show any errors that happened
            if (response && response.error)
            
                // If the report assembly threw an error, display it here
                // This is NOT related to the Javascript error I am experiencing!
            
        );
    
;

【问题讨论】:

【参考方案1】:

您需要在observationsReport.php 上设置X-Frame-Options 的标头以允许同源。

此标头的目的是告诉浏览器他们是否应该允许使用框架来加载页面内容。您的 jQuery 代码不足以克服这个限制。

或者正如 MDN 所说:

X-Frame-Options HTTP 响应标头可用于指示是否应允许浏览器以&lt;frame&gt;&lt;iframe&gt;&lt;object&gt; 呈现页面。网站可以使用它来避免点击劫持攻击,确保其内容不会嵌入到其他网站中。

鉴于您使用的是 PHP,我猜您的 Web 服务器使用 Apache 托管,并且在上面的链接中有一个 Configuring Apache 部分:

要配置 Apache 为所有页面发送 X-Frame-Options 标头,请将其添加到您网站的配置中:

Header always set X-Frame-Options SAMEORIGIN

第二个错误看起来可能与您访问页面的方式有关。我会尝试:

    完全限定您的本地页面:

    'src' : 'https://www.[REDACTED].com/xls/observationsReport.php?'

    然后去掉协议相关部分:

    'src' : '//www.[REDACTED].com/xls/observationsReport.php?'

【讨论】:

以上是关于jQuery 将 iframe 写入 XLS 导致 iPhone 上的沙箱访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

读取 xls,将所有日期转换为正确格式,-> 写入 csv

文本分析 - 无法将 Python 程序的输出写入 csv 或 xls 文件

Python将数据写入excel或者txt,读入csv格式或xls文件

R语言write.xlsx函数将数据写入Excel文件:写入Excel文件并自定义表单的名称将数据写入Excel文件新的表单(sheet)中将文件保存为xls文件格式(而不是xlsx)

libreoffice --convert-to xls 改为写入 OpenDocument 格式

使用 Javascript 或 jQuery 将元素写入子 iframe