1.什么引起了ajax跨域不能的問題 ajax本身實(shí)際上是通過xmlhttprequest對(duì)象來(lái)進(jìn)行數(shù)據(jù)的交互,而瀏覽器出于安全考慮,不允許js代碼進(jìn)行跨域操作,所以會(huì)警告。 2.有什么完美的解決方案么? 沒有。解決方案有不少,但是只能是根據(jù)自己的實(shí)際情況來(lái)選擇。 具體情況有: 一、本域和子域的相互訪問: 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創(chuàng)建動(dòng)態(tài)腳本 解決方法: 一、 如果想做到數(shù)據(jù)的交互,那么www.aa.com和book.aa.com必須由你來(lái)開發(fā)才可以??梢詫ook.aa.com用iframe添加到 www.aa.com的某個(gè)頁(yè)面下,在www.aa.com和iframe里面都加上document.domain = "aa.com",這樣就可以統(tǒng)一域了,可以實(shí)現(xiàn)跨域訪問。就和平時(shí)同一個(gè)域中鑲嵌iframe一樣,直接調(diào)用里面的js就可以了。(這個(gè)辦法我沒有嘗 試,不過理論可行) 二、當(dāng)兩個(gè)域不同時(shí),如果想相互調(diào)用,那么同樣需要兩個(gè)域都是由你來(lái)開發(fā)才可以。用iframe可以實(shí)現(xiàn) 數(shù)據(jù)的互相調(diào)用。解決方案就是用window.location對(duì)象的hash屬性。hash屬性就是http://domian/web /a.htm#dshakjdhsjka 里面的#dshakjdhsjka。利用js改變hash值網(wǎng)頁(yè)不會(huì)刷新,可以這樣實(shí)現(xiàn)通過js訪問hash值來(lái)做到通信。不過除了ie之外其他大部分瀏 覽器只要改變hash就會(huì)記錄歷史,你在前進(jìn)和后退時(shí)就需要處理,非常麻煩。不過再做簡(jiǎn)單的處理時(shí)還是可以用的,具體的代碼我再下面有下載。大體的過程是 頁(yè)面a和頁(yè)面b在不同域下,b通過iframe添加到a里,a通過js修改iframe的hash值,b里面做一個(gè)監(jiān)聽(因?yàn)閖s只能修改hash,數(shù)據(jù) 是否改變只能由b自己來(lái)判斷),檢測(cè)到b的hash值被修改了,得到修改的值,經(jīng)過處理返回a需要的值,再來(lái)修改a的hash值(這個(gè)地方要注意,如果a 本身是那種查詢頁(yè)面的話比如http://domian/web/a.aspx?id=3,在b中直接parent.window.location是無(wú) 法取得數(shù)據(jù)的,同樣報(bào)沒有權(quán)限的錯(cuò)誤,需要a把這個(gè)傳過來(lái),所以也比較麻煩),同樣a里面也要做監(jiān)聽,如果hash變化的話就取得返回的數(shù)據(jù),再做相應(yīng)的 處理。 三、這種情形是最經(jīng)常遇到的,也是用的最多的了。就是www.aa.com和www.bb.com你只能修改一個(gè),也 就是另外一個(gè)是別人的,人家告訴你你要取得數(shù)據(jù)就訪問某某連接參數(shù)是什么樣子的,最后返回?cái)?shù)據(jù)是什么格式的。而你需要做的就是在你的域下新建一個(gè)網(wǎng)頁(yè),讓 服務(wù)器去別人的網(wǎng)站上取得數(shù)據(jù),再返回給你。domain1下的a向同域下的getdata.aspx請(qǐng)求數(shù)據(jù),getdata.aspx向 domain2下的 responsedata.aspx發(fā)送請(qǐng)求,responsedata.aspx返回?cái)?shù)據(jù)給getdata.aspx, getdata.aspx再返回給a,這樣就完成了一次數(shù)據(jù)請(qǐng)求。getdata.aspx在其中充當(dāng)了代理的作用。具體可以看下我的代碼。 四、 這個(gè)和上個(gè)的區(qū)別就是請(qǐng)求是使用<script>標(biāo)簽來(lái)請(qǐng)求的,這個(gè)要求也是兩個(gè)域都是由你來(lái)開發(fā)才行。原理就是js文件注入,在本域內(nèi)的a 內(nèi)生成一個(gè)js標(biāo)簽,它的src指向請(qǐng)求的另外一個(gè)域的某個(gè)頁(yè)面b,b返回?cái)?shù)據(jù)即可,可以直接返回js的代碼。因?yàn)閟cript的src屬性是可以跨域 的。具體看代碼,這個(gè)也比較簡(jiǎn)單。 code: http://www./files/300697/cross_the_site_test_code.rar.html (csdn不能粘貼附件么?) 總結(jié): 第一種情況:域和子域的問題,可以完全解決交互。 第二種情況:跨域,實(shí)現(xiàn)過程非常麻煩,需要兩個(gè)域開發(fā)者都能控制,適用于簡(jiǎn)單交互。 第三種情況:跨域,開發(fā)者只控制一個(gè)域即可,實(shí)現(xiàn)過程需要增加代理取得數(shù)據(jù),是常用的方式。 第四種情況:跨域,兩個(gè)域開發(fā)者都需要控制,返回一段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:///cross-domain_proxy 4. cross domain xmlhttprequest using an iframe proxy http://manual./wikihome/dojodotbook/book75 5. back button support for atlas updatepanels http://www./backbuttonsupport.aspx 6. cross-document messaging hack http://blog./archives/000304.html 7. building mash-ups with "atlas" http://atlas./docs/walkthroughs/devscenarios/bridge.aspx 8. calling web services hosted outside of your application with “atlas” http://blogs./federaldev/archive/2006/07/31/684229.aspx http://www./shared%20documents/presentations%20by%20marc% 20schweigert/callatlaswebserviceindifferentproject.zip 9. ajax tip: passing messages between iframes http://www./weblog/permalink.aspx?guid=3b03cf9d-b589-4838-806e-64efcc0a1a15 10. oscon cross-site ajax slides http://blog./archives/2006/07/oscon_crosssite.html http://www./css/api/joseph-smarr-plaxo-oscon-2006.ppt 11. oscon 2006: cross-site ajax http://www./blogs/2006/07/28/oscon-2006-cross-site-ajax/ 附:【iframe跨域自適應(yīng)高度(兼容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域一個(gè)空白頁(yè)面,防止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); }; /* * 設(shè)置代理頁(yè)的hash值,需要a域傳給b域hostname */ this.sethash=function(){ var asearch=document.location.search.match(/hostname=([^&]+)/); if(!!asearch){ //設(shè)定 代理頁(yè)面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); //動(dòng)態(tài)設(shè)置代理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); } }; }; 本文轉(zhuǎn)發(fā)自:http://zhaohe162.blog.163.com/blog/static/3821679720113219250547/ |
|
來(lái)自: 馬無(wú)夜草不肥啊 > 《javascript》