关于form+iframe跨域后的js回调处理 进入全屏
line

只要是足够大的web项目,一定会遇到iframe跨域的情况,而且问题就在于,跨域后,iframe中如何触发父页面的回调呢?

别告诉我用设置document.domain的方式,因为这个非常不靠谱,而且还会造成一连串的跨域解决问题,只要一个页面设置了domain,该页面嵌入的所有iframe都必须设置domain,才能进行相互访问,否则,非常悲剧。


这里,我们不谈domain,我们说说别的解决方案:iframe+iframe。下面来举个例子。


1、假定http://www.baidufe.com/cmt是专门用来进行评论管理的页面:A在A页面上定义了回调方法:callback,需要在评论提交完成后执行,并将相关数据回传给callback


<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>评论管理</title>
        <script type="text/javascript">
            var callback = function(cmtData){
                // TODO
            };
        </script>
    </head>
    <body>
        <iframe src="#" frameborder="0" id="cmtIframe" name="cmtIframe"></iframe>
        <form action="http://cmt.baidufe.com" target="cmtIframe">
            ...
        </form>
    </body>
</html>

2、评论信息会提交到http://cmt.baidufe.com域下进行处理:B,假设B页面的内容是这样:

<script type="text/javascript">
    parent.callback({isDelete:1});
</script>

仔细分析一下,这已经发生跨域了,cmt.baidufe.com是www.baidufe.com的子域,对于iframe来说,这依然是有跨域限制的。要想在cmt.baidufe.com下访问www.baidufe.com的对象,是无法做到的。


那应该怎么解决?


再分析下,既然在iframe为cmt.baidufe.com的页面下无法访问父页面www.baidufe.com下的对象,那么就是说,浏览器会认为域名不相同,所以不允许js交互。

好,如果把iframe改为www.baidufe.com的页面下,那么就避开了这个问题,就一定能访问到父页面为www.baidufe.com下的对象。这样也就不会存在跨域的问题了。


究竟该怎么实际操作呢?


改变http://cmt.baidufe.com的内容即可:

<iframe src="http://www.baidufe.com/proxy?isDelete=1" frameborder="0"></iframe>

是的,iframe中,再套一层iframe,这个内层iframe指向一个和父页面相同域名的代理文件,并将参数传递下去。

最后处理回调的问题,就可以完全交给这个代理文件了,代理文件可以这么写:

<script type="text/javascript">
    var s = (location.hash || location.search).substr(1).split('&');
    top.callback(isDelete:s[1]);
</script>

是的,其实就这么简单,这样就能非常完美的实现,form表单+iframe跨域时的回调处理。


关于这个代理文件,其实可以写的非常完善,这里就先不弄了,后续有时间再补上!

阿里巴巴-钉钉-开放平台,能力开放&开发者运营岗位招聘中, 期待你的加入!
钉钉开放,让应用开发更简单
充分开放,是钉钉的重要方向!除致力于为开发者打造丰富的开放API, 更易接入的场景化能力包, 完备的应用开发工具之外, 还需要持续构建开放能力的布道、开发者生态运营体系,包括培训、沙龙、大会、社区合作等等。业务在快速发展,我们也还需要更多优秀的小伙伴加入!

评论区域

line
  • Alien 2014-11-25 11:55:13 回复
    回复 js菜鸟 : 莫要抠字眼儿,这都好久的文章了,不过确实解决问题了,之前在狼厂时候用的。技术革新较快,你也可以发掘另外的办法。
    js菜鸟 said:
    一点也不完美。还自称完美解决,汗。。。
  • js菜鸟 2014-11-25 10:56:42 回复
    一点也不完美。还自称完美解决,汗。。。
  • caobaiguo 2014-10-20 11:32:48 回复
    Alien,您好,前端菜鸟请教:
    action="http://cmt.baidufe.com"
    如果没法控制http://cmt.baidufe.com的输出内容,除了后端进行proxy_pass外,还有其他跨域的方法没?
    非常感谢!
  • 小清新 2013-06-29 11:35:26 回复
    好像懂了 再试试