我有一个应用程序( http://localhost/MyApp
),其中某些部件通过IFRAMES渲染。 这些零件的iframe没有业务与应用的DOM的休息,所以我申请的sandbox
属性。
该IFRAME声明如下:
<iframe src="/MyApp/en/html/action?id=1" sandbox="allow-forms allow-scripts" seamless="seamless"></iframe>
该iframed网页上有一个按钮,使一个AJAX调用同一个Web应用程序,但随后而不是HTTP GET
,浏览器发出一个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-origin
的sandbox
属性,它works.As据我读到这里 ,它不应该影响AJAX调用。
这究竟是为什么? 正在考虑的路径/MyApp/en/html/action
作为整个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:
- 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.
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).
Additional info
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>
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.
...and if you embed it without allow-same-origin
:
localhost
XMLHttpRequest cannot load https://google.com/. Cannot make any requests from 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).
Reasoning
Why is it so important to block Ajax calls from sandboxed contents from the same domain? As explained in the article:
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.
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 creates an "animation" that consists of:
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.
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.
When Alice visits Mallory profile, and sees the animation, the script above runs:
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.
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.
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.