IFRAME声明如下:
<iframe src="/MyApp/en/html/action?id=1" sandBox="allow-forms allow-scripts" seamless="seamless"></iframe>
iframed页面有一个按钮,它将AJAX调用到同一个Web应用程序,但是不是HTTP GET,浏览器会发出一个显示为已取消的HTTP选项,并发生错误:
XMLHttpRequest cannot load http://localhost/MyApp/en/data/action?id=1. Cannot make any requests from null. Ajax State 0 Error: HTTP 0
如果我将allow-same-origin添加到沙盒属性中,它可以工作.至于I read here,它不应该影响AJAX调用.
为什么会发生这种情况?考虑将路径/ MyApp / en / html / action作为整个IFRAME的起源,并将请求阻止到以前的级别?
干杯.
解决方法
- Unique origin treatment. All content is treated under a unique origin. The content is not able to traverse the DOM or read cookie information.
This means that even content coming from the same domain is treated with the cross-domain policy,as each IFRAME content will be viewed as a unique origin.
Embedded content is only permitted to display information. No other actions can be done inside the IFRAME that could compromise the hosting website or take advantage of the users’ trust.
换句话说,如果您在沙盒属性中省略了allow-same-origin,那么它将沙盒页面视为属于不同的域(实际上,它将被视为具有原始空白).由于将Ajax请求置空是没有意义的,所以沙盒页面根本无法进行Ajax调用(如果允许他们对本地主机进行访问,那么它们将与父页面的调用无法区分,从而达到沙盒的目的).
附加信息
如果您尝试将Ajax调用到其他域,则显然将失败:
<script src="http://code.jquery.com/jquery.min.js"></script> <script> console.log(location.host); $.post('https://google.com/',{},function() { }); </script>
但是,它将如何失败将取决于所使用的沙箱属性.如果您将页面上面嵌入到具有allow-same-origin的iframe中,则会将其打印到控制台:
localhost XMLHttpRequest cannot load https://google.com/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
…如果你嵌入没有allow-same-origin:
localhost XMLHttpRequest cannot load https://google.com/. Cannot make any requests from null.
请注意,虽然两者都将location.host报告为localhost,但有一个认为源为http:// localhost,而另一个则将其视为null(显示与您在示例中遇到的错误信息相同).
推理
为什么从同一个域中的沙盒内容中阻止Ajax调用非常重要?正如文中所解释的:
It kind of makes sense that content on the same domain should be safe. The risk here primarily stems from user-generated content that is re-hosted in the IFRAME.
举一个例子:假设Facebook决定允许用户在他们的网页上发布一些HTML5动画.它将它们存储在自己的服务器中,并且在显示时,将它们仅作为允许脚本将其沙箱(因为需要脚本才能使动画生效),而是将所有内容都拒绝(特别是允许相同来源,因为您不想要用户代码搞乱了父页面).如果Ajax调用也不会被默认阻止会发生什么?
马洛里创建一个“动画”,其中包括:
>使用其API(例如Open Graph)对Facebook执行Ajax调用;服务器将很乐意接受该呼叫,因为所有这一切都知道请求是从一个以https://facebook.com为起点的页面.
>创建指向自己的服务器的URI,返回的数据作为查询字符串,并将其设置为沙盒页面中的图片的src.
当Alice访问Mallory配置文件并看到动画时,上面的脚本运行:
> Ajax调用运行在Alice的浏览器中,Alice登录;由于服务器不知道呼叫来自哪里(主页或嵌入页面),它将会执行所要求的任何操作 – 包括检索个人信息.>当使用Mallory的URI创建img元素时,浏览器会尝试正常加载“图像”,因为图像不受同源策略的限制.>由于URI在查询字符串中具有Alice的私有信息,Mallory的服务器可以保存它并返回所需的任何图像.现在马洛里有爱丽丝的个人信息,爱丽丝什么都不怀疑.