iframe 跨域实践
近日,接触到一个网页快照功能,后台如何实现,我们暂且不管,程序给我的要求就是需要当前页面的 body 标签的html内容(去除script标签).按照我的想法,基于jquery,使用ajax的post方式提交本页面的body内容(提交内容之前使用正则替换掉script的内容为空字符),后台返回json格式数据js做相关的处理.
想到就做,然后我就这么处理了,而且也果然 在本机调试成功了,乐滋乐滋的上了测试地址,然后我发现自己杯具了:这个有跨域需求...
打个比方:我们当前浏览的页面地址是 http://a.domain.com/a/a.html (也有可能是 http://b.dommain.com/b/b.html 等等任何地址,因为该快照功能被写成一个js文件,需要的页面只需要引入该js文件:snapshot.js 即可实现快照功能) 但是后台程序接受数据的页面地址是 http://f.domain.com/f/ ,而这就存在了一个主域相同,子域不同的问题,存在跨域限制。而我们传送的数据量也许会很大,使用ajax的jsonp方式会自动被转为get方式提交数据,对于我们现在的需求不可行(如果只是传送当前页面的url给后台程序,那就用jsonp方式,方便快捷,而且也可以退坡跨域限制),所以我们只好使用 iframe 来提交数据,具体做法如下:
然后我们看 snapshot.js 的内容:
View Code
<html>
<head>
<meta charset="utf-8" />
<title>snapshot html page</title>
<script type="text/javascript">
document.domain = 'domain.com';// 关键
</script>
</head>
<body>
<form action="http://f.domain.com/f/" method="post">
<textarea name="html"></textarea>
</form>
</body>
</html>
然后,我们在 snapshot.js 文件里面:
View Code
void function(){
var $snapshot;
var _class = {
init: function(){
var html =
'<div id="J_SnapshotWrap">'+
'<iframe src="http://f.domain.com/f/snapshot.html"></iframe>'+// iframe width: 0;height: 0;border: none;
'<button type="button">快照</button>'+
'</div>';
$('body').append(html);
$snapshot = $('#J_SnapshotWrap');
$snapshot.find('button').on('click', _class.event.buttonClick:);
},
event: {
buttonClick: function(){
var $iframe = $snapshot.find('iframe'), bodyContent = $('body').replace(new RegExp("<script.*<\/script>", 'ig'), '');
document.domain = 'dommain.com'; // 关键, 保证当前页与iframe页面的 document.domain 是相等的
$iframe.contents().find('body').find('textarea[name=html]').val(bodyContent);
$iframe.contents().find('body').find('form').submit();
$iframe.attr('data-load', '1');
$(this).off('clcik');// 只能点击一次,一个页面只能生成一次快照
$(this).on('mouseenter', _class.event.buttonMouseenter);
$(this).on('mouseleave', _class.event.buttonMouseleave);
},
buttonMouseenter: function(){
},
buttonMouseleave: function(){
}
}
};
_class.init();
}();
});
这样我们就能跨域提交大容量数据了。
这里主要跨域是设置当前页的 document.domain = 主域,iframe 的document.domain = 主域 这样实现的。
这里还有个事情就是,提交的数据生成了图片,图片地址如何让当前页得到呢?这个又涉及到iframe通信,我的做法比较笨,就是给iframe页面生成一个input隐藏域,把图片地址赋值进去,然后在父页面,鼠标移动到button上时进行判断,判断iframe的data-load是否为‘1’,然后取子页面的隐藏域的值。
更进一步:
下面是一些跨域的资料,列出来作为参考:
JSONP跨域的原理解析http://www.nowamagic.net/librarys/veda/detail/224
设置 iframe document.domain杂谈 http://lixinlixin2008.iteye.com/blog/515352
iFrame跨域解决办法 http://blog.sina.com.cn/s/blog_63940ce201015w0d.html


浙公网安备 33010602011771号