IFRAME 沙箱属性阻止 AJAX 调用 [英] IFRAME sandbox attribute is blocking AJAX calls

查看:21
本文介绍了IFRAME 沙箱属性阻止 AJAX 调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an application (http://localhost/MyApp), where some of the parts are rendered through IFRAMES. These iframed parts has no business with the rest of the application's DOM, so I applied the sandbox attribute.

IFRAME 声明如下:

The IFRAME is declared like this:

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

iframe 页面有一个按钮,可以对同一个 Web 应用程序进行 AJAX 调用,但浏览器发出的不是 HTTP GET,而是出现的 HTTP OPTIONSCancelled,并发生错误:

The iframed page has a button that makes a AJAX call to the same web application, but then rather than a HTTP GET, the browser issues a HTTP OPTIONS that appears as Cancelled, and an error happens:

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 添加到 sandbox 属性,它会起作用.就 我在这里读到,它不应该影响 AJAX 调用.

If I add the allow-same-origin to the sandbox attribute, it works.As far as I read here, it was not supposed to affect AJAX calls.

为什么会这样?是否考虑将路径 /MyApp/en/html/action 作为整个 IFRAME 的来源并阻止对先前级别的请求?

Why is this happening? Is considering the path /MyApp/en/html/action as origin of the whole IFRAME and blocking the request to previous levels?

干杯.

推荐答案

它影响 Ajax 的原因是因为 Ajax 受 同源策略 规则,当您对其进行沙盒处理时,您实际上是在告诉浏览器将 iframe 内容视为来自不同的来源.引用相同的文章:

The reason it affects Ajax is because Ajax is governed by the Same Origin Policy rules, and when you sandbox it you're effectively telling the browser to treat the iframe contents as if it were from a different origin. Quoting the same article:

  • 独特来源处理.所有内容均根据独特来源进行处理.内容无法遍历 DOM 或读取 cookie 信息.
  • Unique origin treatment. All content is treated under a unique origin. The content is not able to traverse the DOM or read cookie information.

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

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.

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

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.

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

In other words, if you omit the allow-same-origin in the sandbox attribute, it will treat the sandboxed page as belonging to a different domain (in fact, it will treat as having a null origin). Since it doesn't make sense to make Ajax requests to null, sandboxed pages can not make Ajax calls at all (if making them to localhost were allowed they would be indistinguishable from the calls from the parent page, defeating the purpose of sandboxing).

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

If you try to make an Ajax call to a different domain, it will obviously fail:

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

但是,如何失败将取决于所使用的沙箱属性.如果您将上面的页面嵌入到带有 allow-same-originiframe 中,它将打印到控制台:

However, how it will fail will depend on the sandbox attribute used. If you embed the page above in an iframe with allow-same-origin it will print this to the console:

localhost
XMLHttpRequest cannot load https://google.com/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.

...如果你嵌入它没有 allow-same-origin:

...and if you embed it without allow-same-origin:

localhost
XMLHttpRequest cannot load https://google.com/. Cannot make any requests from null.

请注意,虽然两者都将 location.host 报告为 localhost,但一个认为源是 http://localhost 而另一个认为它是 null(显示您在示例中遇到的相同错误消息).

Note that, while both reported location.host as localhost, one considered the origin to be http://localhost while the other considered it to be null (showing the same error message you experienced in your example).

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

Why is it so important to block Ajax calls from sandboxed contents from the same domain? As explained in the article:

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

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 动画.它将它们存储在自己的服务器中,并在显示时将它们沙箱化为 allow-scripts(因为动画需要脚本才能工作),但拒绝其他所有内容(特别是 allow-同源,因为您不希望用户代码弄乱父页面).如果默认情况下 Ajax 调用也没有被阻止,会发生什么情况?

Let's make up an example: suppose Facebook decides to allow users post little HTML5 animations in their pages. It stores them in its own servers and, when displaying, sandboxes them as allow-scripts only (because scripts are needed for the animations to work) but leave everything else denied (in particular allow-same-origin, since you don't want user code messing up with the parent page). What would happen if Ajax calls weren't also blocked by default?

Mallory 创建了一个动画"包括:

Mallory creates an "animation" that consists of:

  1. 使用其 API 对 Facebook 执行 Ajax 调用(例如,打开图);服务器会很高兴地接受调用,因为它知道请求来自以 https://facebook.com 为源的页面.

  1. Performing an Ajax call to Facebook, using its API (say, Open Graph); the server will happily accept the call, since for all it knows the request came from a page with https://facebook.com as origin.

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

Create a URI pointing to her own server, with the returned data as query strings, and set it as the src of a picture in the sandboxed page.

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

When Alice visits Mallory profile, and sees the animation, the script above runs:

  1. Ajax 调用在 Alice 的浏览器中运行,而 Alice 已登录;由于服务器不知道调用来自何处(主页或嵌入页面),它会执行任何它要求的操作 - 包括检索个人信息.

  1. The Ajax call runs in Alice's browser, while Alice is logged on; since the server does not know where the call comes from (main page or embedded page) it will do whatever it's asked to - including retrieving personal info.

当使用 Mallory 的 URI 创建 img 元素时,浏览器将尝试加载图像".通常,因为图像不受同源政策的约束.

When the img element is created with Mallory's URI, the browser will attempt to load the "image" normally, since images are exempt from the Same Origin Policy.

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

Since the URI has Alice's private info in the query string, Mallory's server can just save it and return whatever image it wants. Now Mallory has Alice's personal info, and Alice suspects nothing.

这篇关于IFRAME 沙箱属性阻止 AJAX 调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆