12

我有一个应用程序 ( http://localhost/MyApp),其中一些部分是通过 IFRAMES 呈现的。这些 iframed 部分与应用程序的 DOM 的其余部分无关,因此我应用了该sandbox属性。

IFRAME 声明如下:

<iframe src="/MyApp/en/html/action?id=1" sandbox="allow-forms allow-scripts" seamless="seamless"></iframe>

HTTP GETiframed 页面有一个按钮,可以对同一个 Web 应用程序进行 AJAX 调用,但是浏览器发出的不是 ,而是HTTP OPTIONS显示为 的Cancelled,并且发生错误:

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-originsandbox属性中,它会起作用。据我在这里阅读,它不应该影响 AJAX 调用。

为什么会这样?是否将路径/MyApp/en/html/action视为整个 IFRAME 的起源并将请求阻止到先前级别?

干杯。

4

1 回答 1

27

它影响 Ajax 的原因是因为 Ajax 受同源策略规则的约束,并且当您对它进行沙箱处理时,您实际上是在告诉浏览器将iframe内容视为来自不同的来源。引用同一篇文章

  • 独特的原产地处理。所有内容均在唯一来源下处理。内容无法遍历 DOM 或读取 cookie 信息。

这意味着即使来自同一域的内容也会被跨域策略处理,因为每个IFRAME内容都将被视为唯一的来源。

嵌入的内容只允许显示信息。不能在IFRAME内进行任何可能损害托管网站或利用用户信任的其他操作。

换句话说,如果您省略属性allow-same-origin中的sandbox,它会将沙盒页面视为属于不同的域(实际上,它将视为具有null来源)。由于向 发出 Ajax 请求没有意义null,因此沙盒页面根本无法进行 Ajax 调用(如果localhost允许它们进行 Ajax 调用,它们将与来自父页面的调用无法区分,从而违背了沙盒的目的)。

附加信息

如果您尝试对不同的域进行 Ajax 调用,它显然会失败:

<script src="http://code.jquery.com/jquery.min.js"></script>
<script>
    console.log(location.host);
    $.post('https://google.com/',{},function() { });
</script>

但是,它将如何失败将取决于所使用的沙盒属性。如果您将上面的页面嵌入到iframe其中,allow-same-origin它会将其打印到控制台:

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.hostlocalhost,但一个认为起源是http://localhost,而另一个认为它是null(显示您在示例中遇到的相同错误消息)。

推理

为什么阻止来自同一域的沙盒内容的 Ajax 调用如此重要?如文章中所述:

同一域上的内容应该是安全的,这是有道理的。这里的风险主要来自重新托管在IFRAME中的用户生成内容。

让我们举个例子:假设 Facebook 决定允许用户在他们的页面中发布小的 HTML5 动画。它将它们存储在自己的服务器中,并在显示时将它们作为allow-scripts唯一的沙箱(因为动画需要脚本才能工作)但拒绝其他所有内容(特别是allow-same-origin,因为您不希望用户代码弄乱父页面)。如果默认情况下也没有阻止 Ajax 调用会发生什么?

Mallory 创建了一个“动画”,其中包括:

  1. 使用 Facebook 的 API(比如Open Graph )对 Facebook 执行 Ajax 调用;服务器会很高兴地接受这个调用,因为它知道请求来自一个https://facebook.com作为源的页面。

  2. 创建一个指向她自己的服务器的 URI,将返回的数据作为查询字符串,并将其设置为src沙盒页面中的图片。

当 Alice 访问 Mallory 个人资料并看到动画时,上面的脚本运行:

  1. Ajax 调用在 Alice 的浏览器中运行,而 Alice 已登录;由于服务器不知道呼叫来自哪里(主页或嵌入式页面),它会做任何它被要求做的事情——包括检索个人信息。

  2. img使用 Mallory 的 URI 创建元素时,浏览器将尝试正常加载“图像”,因为图像不受同源策略的约束。

  3. 由于 URI 在查询字符串中有 Alice 的私人信息,Mallory 的服务器可以保存它并返回它想要的任何图像。现在马洛里有了爱丽丝的个人信息,爱丽丝一点也不怀疑。

于 2013-01-31T06:14:57.570 回答