<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Architecting Life &#187; Security</title>
	<atom:link href="http://xujiwei.com/blog/tags/security/feed/" rel="self" type="application/rss+xml" />
	<link>http://xujiwei.com/blog</link>
	<description>Just do it</description>
	<lastBuildDate>Wed, 28 Dec 2011 02:06:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>在 AIR 中突破同源策略访问 iframe 中的内容</title>
		<link>http://xujiwei.com/blog/access-iframe-in-air/</link>
		<comments>http://xujiwei.com/blog/access-iframe-in-air/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 12:20:15 +0000</pubDate>
		<dc:creator>Xu Jiwei</dc:creator>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[iframe]]></category>
		<category><![CDATA[Sandbox]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://tmp.xujiwei.com/blog/?p=139</guid>
		<description><![CDATA[<a href="http://xujiwei.com/blog/access-iframe-in-air/" title="在 AIR 中突破同源策略访问 iframe 中的内容"></a>本篇所讲关于 AIR 的内容是基本 HTML+JS，而不是 Flex 或其他。 在 AIR 中，如果当前页面有一个 iframe，并且我们需要获取这个 iframe 的内容，但是如果 iframe 里包含的是远程页面，在默认情况下，浏览器策略并不允许这种情况，这就是同源策略的限制。 在 Titanium 这个类似于 AIR 的平台中，默认情况下是可以直接从应用的页面中去读取 iframe 中的内容而没有任何限制，但是在 AIR 中不可以。在网上搜索了一番，再看了好几遍 AIR 的文档之后，终于找到解决问题的方法了。 在 AIR 中，iframe 标签拥有额外的几个属性：sandboxRoot、documentRoot、allowCrossDomainXHR 及 ondominitialize。这里为了解决读取 iframe 内容所用到的属性就是 sandboxRoot 及 documentRoot。 通过 sandboxRoot 及 documentRoot，可以将本地的页面映射为远程页面，并在沙盒中运行，另外，在沙盒中运行的页面就会拥有映射域名的域。例如，我们可以将本地的 proxy.html 映射为 http://example.com/local/proxy.html，这样，在实际运行时，proxy.html 中如果用 document.domain 获取页面所在的域，就会得到 example.com，这个时候如果在 proxy.html 中添加一个 iframe，这个 iframe 指向我们实际需要获取内容的地址，因为域相同，就可以直接获取 iframe 的内容了。 例如，我们要在 AIR 中获取 http://example.com/member/login.html 的内容，或者操作这个页面的元素，就可以先用一个 proxy.html，用来实现将本地文件运行在沙盒中，再用一个 login.html 来对实际网页进行操作。 &#60;!&#8211; proxy.html &#8211;&#62; &#60;iframe src=&#8221;http://example.com/local/login.html&#8221; id=&#8221;frame&#8221; width=&#8221;100%&#8221; sandboxRoot=&#8221;http://example.com/local/&#8221; documentRoot=&#8221;app:/&#8221; name=&#8221;frame&#8221; height=&#8221;100%&#8221;&#62;&#60;/iframe&#62; &#60;!&#8211; login.html &#8211;&#62; &#60;iframe id=&#8217;f' frameborder=&#8221;0&#8243; scrolling=&#8221;no&#8221; src=&#8221;http://example.com/member/login.html&#8221; width=&#8221;100%&#8221; height=&#8221;100%&#8221;&#62;&#60;/iframe&#62; &#60;script type=&#8221;text/javascript&#8221;&#62; alert(document.domain); var f = document.getElementById(&#8216;f&#8217;); f.onload = function() { alert(f.contentWindow.document.documentElement.innerHTML); }; &#60;/script&#62; 在 proxy.html 中，虽然 iframe 的 src 属性是 http://example.com/locale/login.html，但是由于这个 iframe 具有 sandboxRoot 属性，所以实际请求会被重定向到相对于 sandboxRoot，并且使用 documentRoot 进行定位的实际地址 app://login.html，但是这个时候 login.html 中具有  document.domain=&#8221;example.com&#8221; 这个属性，所有可以直接使用 iframe.contentWindow 来访问 iframe 中的内容。 虽然解决方法有些麻烦，但终归可以实现突破同源策略的限制来读取 iframe 的内容了。 当然，如果你有更好的方法，请不吝赐教：）]]></description>
			<content:encoded><![CDATA[<a href="http://xujiwei.com/blog/access-iframe-in-air/" title="在 AIR 中突破同源策略访问 iframe 中的内容"></a><div class="post-content">

本篇所讲关于 AIR 的内容是基本 HTML+JS，而不是 Flex 或其他。

在 <a rel="external" href="get.adobe.com/air/">AIR</a> 中，如果当前页面有一个 iframe，并且我们需要获取这个 iframe 的内容，但是如果 iframe 里包含的是远程页面，在默认情况下，浏览器策略并不允许这种情况，这就是同源策略的限制。

在 <a rel="external" href="http://www.appcelerator.com">Titanium</a> 这个类似于 AIR 的平台中，默认情况下是可以直接从应用的页面中去读取 iframe 中的内容而没有任何限制，但是在 AIR 中不可以。在网上搜索了一番，再看了好几遍 AIR 的文档之后，终于找到解决问题的方法了。

在 AIR 中，<a rel="external" href="http://help.adobe.com/en_US/AIR/1.5/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7eb2.html#WS5b3ccc516d4fbf351e63e3d118666ade46-7edb">iframe 标签拥有额外的几个属性</a>：sandboxRoot、documentRoot、allowCrossDomainXHR 及 ondominitialize。这里为了解决读取 iframe 内容所用到的属性就是 sandboxRoot 及 documentRoot。

通过 sandboxRoot 及 documentRoot，可以将本地的页面映射为远程页面，并在沙盒中运行，另外，在沙盒中运行的页面就会拥有映射域名的域。例如，我们可以将本地的 proxy.html 映射为 http://example.com/local/proxy.html，这样，在实际运行时，proxy.html 中如果用 document.domain 获取页面所在的域，就会得到 example.com，这个时候如果在 proxy.html 中添加一个 iframe，这个 iframe 指向我们实际需要获取内容的地址，因为域相同，就可以直接获取 iframe 的内容了。

例如，我们要在 AIR 中获取 http://example.com/member/login.html 的内容，或者操作这个页面的元素，就可以先用一个 proxy.html，用来实现将本地文件运行在沙盒中，再用一个 login.html 来对实际网页进行操作。
<blockquote>
<div id="CODE_6635" class="codeMain"><span style="font-style: normal;">&lt;!&#8211; proxy.html &#8211;&gt;
&lt;iframe src=&#8221;http://example.com/local/login.html&#8221; id=&#8221;frame&#8221; width=&#8221;100%&#8221;
sandboxRoot=&#8221;http://example.com/local/&#8221;
documentRoot=&#8221;app:/&#8221; name=&#8221;frame&#8221; height=&#8221;100%&#8221;&gt;&lt;/iframe&gt;</span></div></blockquote>
<blockquote>
<div id="CODE_4316" class="codeMain">
<ul></ul>
<em><span style="font-style: normal;">&lt;!&#8211; login.html &#8211;&gt;</span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;">&lt;iframe id=&#8217;f' frameborder=&#8221;0&#8243; scrolling=&#8221;no&#8221;</span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;"> src=&#8221;http://example.com/member/login.html&#8221; </span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;"> width=&#8221;100%&#8221; height=&#8221;100%&#8221;&gt;&lt;/iframe&gt;</span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;">&lt;script type=&#8221;text/javascript&#8221;&gt;</span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;">alert(document.domain);</span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;">var f = document.getElementById(&#8216;f&#8217;);</span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;">f.onload = function() {</span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;"> alert(f.contentWindow.document.documentElement.innerHTML);</span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;">};</span></em><span style="font-style: normal;">
</span><em><span style="font-style: normal;">&lt;/script&gt;</span></em></div></blockquote>
在 proxy.html 中，虽然 iframe 的 src 属性是 http://example.com/locale/login.html，但是由于这个 iframe 具有 sandboxRoot 属性，所以实际请求会被重定向到相对于 sandboxRoot，并且使用 documentRoot 进行定位的实际地址 app://login.html，但是这个时候 login.html 中具有  document.domain=&#8221;example.com&#8221; 这个属性，所有可以直接使用 iframe.contentWindow 来访问 iframe 中的内容。

虽然解决方法有些麻烦，但终归可以实现突破同源策略的限制来读取 iframe 的内容了。

当然，如果你有更好的方法，请不吝赐教：）

</div>
]]></content:encoded>
			<wfw:commentRss>http://xujiwei.com/blog/access-iframe-in-air/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

