`
azhangwq
  • 浏览: 5946 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

【转发】ajax跨域、iframe跨域和JS跨域通信的几种解决方案

 
阅读更多
1.什么引起了ajax跨域不能的问题 
ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告。 

2.有什么完美的解决方案么? 
没有。解决方案有不少,但是只能是根据自己的实际情况来选择。 

具体情况有: 
一、本域和子域的相互访问: www.aa.com和book.aa.com 
二、本域和其他域的相互访问: www.aa.com和www.bb.com 用 iframe 
三、本域和其他域的相互访问: www.aa.com和www.bb.com 用 XMLHttpRequest访问代理 
四、本域和其他域的相互访问: www.aa.com和www.bb.com 用 JS创建动态脚本 


解决方法: 
一、 如果想做到数据的交互,那么www.aa.com和book.aa.com必须由你来开发才可以。可以将book.aa.com用iframe添加到 www.aa.com的某个页面下,在www.aa.com和iframe里面都加上document.domain = "aa.com",这样就可以统一域了,可以实现跨域访问。就和平时同一个域中镶嵌iframe一样,直接调用里面的JS就可以了。(这个办法我没有尝 试,不过理论可行) 


二、当两个域不同时,如果想相互调用,那么同样需要两个域都是由你来开发才可以。用iframe可以实现 数据的互相调用。解决方案就是用window.location对象的hash属性。hash属性就是http://domian/web /a.htm#dshakjdhsjka 里面的#dshakjdhsjka。利用JS改变hash值网页不会刷新,可以这样实现通过JS访问hash值来做到通信。不过除了IE之外其他大部分浏 览器只要改变hash就会记录历史,你在前进和后退时就需要处理,非常麻烦。不过再做简单的处理时还是可以用的,具体的代码我再下面有下载。大体的过程是 页面a和页面b在不同域下,b通过iframe添加到a里,a通过JS修改iframe的hash值,b里面做一个监听(因为JS只能修改hash,数据 是否改变只能由b自己来判断),检测到b的hash值被修改了,得到修改的值,经过处理返回a需要的值,再来修改a的hash值(这个地方要注意,如果a 本身是那种查询页面的话比如http://domian/web/a.aspx?id=3,在b中直接parent.window.location是无 法取得数据的,同样报没有权限的错误,需要a把这个传过来,所以也比较麻烦),同样a里面也要做监听,如果hash变化的话就取得返回的数据,再做相应的 处理。 


三、这种情形是最经常遇到的,也是用的最多的了。就是www.aa.com和www.bb.com你只能修改一个,也 就是另外一个是别人的,人家告诉你你要取得数据就访问某某连接参数是什么样子的,最后返回数据是什么格式的。而你需要做的就是在你的域下新建一个网页,让 服务器去别人的网站上取得数据,再返回给你。domain1下的a向同域下的GetData.aspx请求数据,GetData.aspx向 domain2下的 ResponseData.aspx发送请求,ResponseData.aspx返回数据给GetData.aspx, GetData.aspx再返回给a,这样就完成了一次数据请求。GetData.aspx在其中充当了代理的作用。具体可以看下我的代码。 


四、 这个和上个的区别就是请求是使用<script>标签来请求的,这个要求也是两个域都是由你来开发才行。原理就是JS文件注入,在本域内的a 内生成一个JS标签,它的SRC指向请求的另外一个域的某个页面b,b返回数据即可,可以直接返回JS的代码。因为script的src属性是可以跨域 的。具体看代码,这个也比较简单。 

code: 
http://www.live-share.com/files/300697/Cross_The_Site_Test_code.rar.html 
(csdn不能粘贴附件么?) 

总结: 
第一种情况:域和子域的问题,可以完全解决交互。 
第二种情况:跨域,实现过程非常麻烦,需要两个域开发者都能控制,适用于简单交互。 
第三种情况:跨域,开发者只控制一个域即可,实现过程需要增加代理取得数据,是常用的方式。 
第四种情况:跨域,两个域开发者都需要控制,返回一段js代码。 

PS:代码自己按照情况修改即可。 

这是拿别人的参考链接,老美的文章比较多。 

1. Security Considerations: Dynamic HTML 
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/sec_dhtml.asp 

2. About Cross-Frame Scripting and Security 
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/om/xframe_scripting_security.asp 

3. Cross-Domain Proxy 
http://ajaxpatterns.org/Cross-Domain_Proxy 

4. Cross Domain XMLHttpRequest using an IFrame Proxy 
http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book75 

5. Back Button Support for Atlas UpdatePanels 
http://www.nikhilk.net/BackButtonSupport.aspx 

6. Cross-document messaging hack 
http://blog.monstuff.com/archives/000304.html 

7. Building Mash-ups with "Atlas" 
http://atlas.asp.net/docs/Walkthroughs/DevScenarios/bridge.aspx 

8. Calling web services hosted outside of your application with “Atlas” 
http://blogs.msdn.com/federaldev/archive/2006/07/31/684229.aspx 

http://www.federaldeveloper.com/Shared%20Documents/Presentations%20by%20Marc% 

20Schweigert/CallAtlasWebServiceInDifferentProject.zip 

9. AJAX Tip: Passing Messages Between iframes 
http://www.25hoursaday.com/weblog/PermaLink.aspx?guid=3b03cf9d-b589-4838-806e-64efcc0a1a15 

10. OSCON Cross-site Ajax Slides 
http://blog.plaxo.com/archives/2006/07/oscon_crosssite.html 

http://www.plaxo.com/css/api/Joseph-Smarr-Plaxo-OSCON-2006.ppt 

11. OSCON 2006: Cross-site Ajax 
http://www.sitepoint.com/blogs/2006/07/28/oscon-2006-cross-site-ajax/


附:【Iframe跨域自适应高度(兼容IE/Firefox)终极解决方案】

main.html在A域,被包含的iframe.html、proxy.html以及proxy.js在B域

main.html

<script type="text/javascript" src="http://zhaohe162.blog.163.com/blog/B域/proxy.js"></script>
<script type="text/javascript">
var aai=new AutoAdjustIframe();
aai.autoAdjust('frameName');
</script>

<div style="border:1px solid #ccc;padding:10px;">
<iframe id="frameName" name="frameName" src="http://zhaohe162.blog.163.com/blog/B域/iframe.html?hostname=192.168.1.100:8080" style="width:100%;border:1px solid #f00;" scrolling="no" frameborder="0"></iframe>
</div>
<br/>尾部<br/>

iframe.html

文字<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
文字<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
文字<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
文字<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
文字<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
文字<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
文字<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
文字<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
文字<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<script type="text/javascript" src="http://zhaohe162.blog.163.com/blog/proxy.js"></script>

<script type="text/javascript">
var aai=new AutoAdjustIframe();
aai.setHash();
</script>

proxy.html
B域一个空白页面,防止404

proxy.js

  var AutoAdjustIframe=function(){
    var autoSecond=1;
    this.autoAdjust=function(iframeId){
        setInterval(function(){
            try{
                var height=parseFloat(window.frames[iframeId].frames[iframeId+'-proxyiframe'].location.hash.replace(/^#/,''))||100;
                document.getElementById(iframeId).style.height=height+'px';
            }catch(e){};
        },autoSecond);
    };
    var getHeight=function(){
        return Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,
document.documentElement.clientHeight,document.body.clientHeight);
    };
    /*
     * 设置代理页的hash值,需要A域传给B域hostname
     */
    this.setHash=function(){
        var aSearch=document.location.search.match(/hostname=([^&]+)/);
        if(!!aSearch){
            //设定 代理页面url
            var proxyUrl='http://'+aSearch[1]+'/proxy.html';
            var height=getHeight();
            try{
                console.log('proxyUrl:'+proxyUrl+'\nThe Iframe\'s height:'+height);
            }catch(e){};
            //生成代理iframe
            var iframe=document.createElement('iframe');
            iframe.src=proxyUrl+'#'+height;
            iframe.id=window.name+'-proxyiframe';
            iframe.name=window.name+'-proxyiframe';
            iframe.style.display='none';
            document.body.appendChild(iframe);
            //动态设置代理iframe的hash,以便重新获取新的高度
            var interval=setInterval(function(){
                if(getHeight()!=height){
                    height=getHeight();
                    iframe.src=proxyUrl+'#'+height;
                    try{
                        console.log('Reloading,The Iframe\'s height:'+height);
                    }catch(e){};
                }
            },autoSecond);
        }
    };
};

本文转发自:http://zhaohe162.blog.163.com/blog/static/3821679720113219250547/
分享到:
评论

相关推荐

    Ajax跨域访问解决方案

    **Ajax跨域访问解决方案** 在Web开发中,Ajax(Asynchronous JavaScript and XML)技术被广泛用于实现页面的异步更新,提升用户体验。然而,由于浏览器的同源策略限制,Ajax请求只能向同源(协议、域名和端口相同)...

    js跨域解决方案

    4. **IFrame跨域通信**:利用`window.postMessage`方法,可以在属于不同源的两个IFrame之间进行通信。这种方法适用于页面嵌套场景,但不适用于跨域API调用。 5. **WebSocket跨域**:WebSocket协议本身支持跨域,...

    ajax跨域解决办法

    【AJAX跨域解决办法】 在Web开发中,AJAX(Asynchronous JavaScript and XML)是一种在无需刷新整个页面的情况下更新部分网页的技术。然而,由于浏览器的同源策略限制,AJAX请求通常只能发送到与当前页面同一源的...

    完美解决iframe跨域问题

    总结,通过理解iframe跨域问题的本质以及各种解决方案,我们可以根据实际需求选择合适的策略。`window.name`跨域通信虽然存在一定的局限性,但在某些场景下能提供一种实用的跨域数据传递手段。在实际开发中,结合...

    解决ajax跨域问题

    为了解决AJAX跨域问题,开发者可以采用以下几种策略: 1. JSONP(JSON with Padding) JSONP是一种绕过同源策略的方法,它利用了`&lt;script&gt;`标签不受同源策略限制的特点。JSONP的工作原理是服务器提供一个可被调用的...

    Ajax跨域传输参数

    如果想做到数据的交互,那么www.aa.com和book.aa.com必须由你来开发才可以。可以将book.aa.com用iframe添加到 www.aa.com的某个页面下,在www.aa.com和...就和平时同一个域中镶嵌iframe一样,直接调用里面的JS就可以了

    IE7 Ajax跨域问题

    1. **JSONP (JSON with Padding)**:这是一种常见的跨域解决方案,它通过动态创建`&lt;script&gt;`标签来加载来自其他域的JavaScript代码,因为脚本标签不受同源策略限制。服务器返回的JSON数据被包装在一个函数调用中,...

    怎样实现Ajax 跨域访问

    ### 如何实现Ajax跨域访问 ...以上五种方法分别针对不同的应用场景和技术背景,开发者可以根据实际情况选择最合适的解决方案。需要注意的是,在使用任何一种跨域技术时都应充分考虑安全性问题,避免引入不必要的风险。

    JQuery跨域访问解决方案

    如果需要使用POST方式进行跨域,可以采取其他技术,如CORS(跨源资源共享)或使用IFrame和窗体提交。但是,jQuery本身并不直接支持JSONP之外的跨域POST请求。 在上面的例子中,`$.ajax()`方法用于发起跨域请求,`...

    跨域 iframe 实例 (Cross-Domain Javascript execution library)

    在JavaScript执行库的上下文中,"跨域iframe"通常指的是一个工具或方法,用于在iframe之间安全地共享数据和执行代码,尽管它们的源域可能不相同。这种技术主要应用于解决浏览器的同源策略限制,同源策略是Web浏览器...

    js跨域问题解决方案.

    本文将深入探讨JavaScript跨域问题的原因、影响以及多种解决方案,帮助开发者理解和解决这个问题。 ### 1. 同源策略 同源策略是浏览器为了安全考虑而实施的一项机制,它规定了只有相同协议(http、https等)、相同...

    signalR跨域及解决方案

    总结起来,SignalR 跨域问题的解决方案主要依赖于 CORS 配置,同时可以结合其他技术如 JSONP、代理服务器、IFrame 和 PostMessage,以及 WebSocket 协议,根据实际项目需求选择合适的解决方案。正确配置后,SignalR ...

    用iframe设置代理解决ajax跨域请求问题

    今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到ajax跨域请求的问题。于是想用代理的方式来解决这个跨域问题。 什么是跨域?简单的来说,出于安全方面的考虑,页面中的JavaScript无法访问其他...

    解决ASP.NET AJAX在frame及iframe中跨域访问的问题

    1、为ScriptManager添加脚本引用,不从ScriptResource.axd中加载MicrosoftAjax.js脚本,而是直接加载 &lt;asp:ScriptReference Name="MicrosoftAjax.js" ScriptMode="auto" Path="~/ScriptLibrary/System.Web....

    关于iframe跨域POST提交的方法示例

    以前在面试的时候经常遇到问关于跨域的事儿,所以自己对跨域有一定的概念性了解,知道什么是跨域以及解决跨域的方法,但是具体实际从来没有操作过,直到最近在公司项目中,遇到了一个需要使iframe跨域进行POST提交的...

    iframe跨域调用父窗口js.zip

    要解决iframe跨域调用父页面js方法的问题,我们可以利用以下几种技术: 1. **HTML5的postMessage和message事件**:这是现代浏览器支持的一种跨域通信方式。在iframe中,我们可以使用`window.parent.postMessage...

    JS跨域访问解决方案总结

    JavaScript(JS)跨域访问是Web开发中一个常见的挑战,由于浏览器的安全策略,不同源的JavaScript代码不能直接访问或操作彼此的数据。这里的“域”通常指的是协议+域名+端口的组合。当一个网页尝试从不同于其源的URL...

    跨域解决方案

    今天,我们主要讨论 jsonp 跨域和 document.domain + iframe 跨域这两种解决方案。 Jsonp 跨域 jsonp 是一种常见的解决方案,通常用于减轻 web 服务器的负载。我们可以通过动态创建 script 标签,请求一个带参数的...

Global site tag (gtag.js) - Google Analytics