关于跨域,以及跨域的几种方式
首先我們來(lái)想一想
? ? ? ? ? ? ? 為什么會(huì)有跨域這個(gè)名詞的出現(xiàn)呢?
? ? ? ? ? ? ? 跨域又是什么呢?為何要跨域?
? ? ? ? ? ? ? 瀏覽器的同源策略又是什么?怎么解決?
? ? ? ? ? ? ? jsonp又是什么?
? ? ? ? ? ? ? 跨域的原理又是什么呢?
名詞解釋:
跨域:
瀏覽器對(duì)于javascript的同源策略的限制,例如a.cn下面的js不能調(diào)用b.cn中的js,對(duì)象或數(shù)據(jù)(因?yàn)閍.cn和b.cn是不同域),所以跨域就出現(xiàn)了.
上面提到的,同域的概念又是什么呢??? 簡(jiǎn)單的解釋就是相同域名,端口相同,協(xié)議相同
請(qǐng)求的url地址,必須與瀏覽器上的url地址處于同域上,也就是域名,端口,協(xié)議相同.
比如:我在本地上的域名是study.cn,請(qǐng)求另外一個(gè)域名一段數(shù)據(jù)
這個(gè)時(shí)候在瀏覽器上會(huì)報(bào)錯(cuò):
這個(gè)就是同源策略的保護(hù),如果瀏覽器對(duì)javascript沒(méi)有同源策略的保護(hù),那么一些重要的機(jī)密網(wǎng)站將會(huì)很危險(xiǎn)~
jsonp:
jsonp?全稱是JSON with Padding,是為了解決跨域請(qǐng)求資源而產(chǎn)生的解決方案,是一種依靠開(kāi)發(fā)人員創(chuàng)造出的一種非官方跨域數(shù)據(jù)交互協(xié)議。
一個(gè)是描述信息的格式,一個(gè)是信息傳遞雙方約定的方法。
jsonp的產(chǎn)生:
1.AJAX直接請(qǐng)求普通文件存在跨域無(wú)權(quán)限訪問(wèn)的問(wèn)題,不管是靜態(tài)頁(yè)面也好.
2.不過(guò)我們?cè)谡{(diào)用js文件的時(shí)候又不受跨域影響,比如引入jquery框架的,或者是調(diào)用相片的時(shí)候
3.凡是擁有scr這個(gè)屬性的標(biāo)簽都可以跨域例如<script><img><iframe>
4.如果想通過(guò)純web端跨域訪問(wèn)數(shù)據(jù)只有一種可能,那就是把遠(yuǎn)程服務(wù)器上的數(shù)據(jù)裝進(jìn)js格式的文件里.
5.而json又是一個(gè)輕量級(jí)的數(shù)據(jù)格式,還被js原生支持
6.為了便于客戶端使用數(shù)據(jù),逐漸形成了一種非正式傳輸協(xié)議,人們把它稱作JSONP,該協(xié)議的一個(gè)要點(diǎn)就是允許用戶傳遞一個(gè)callback?參數(shù)給服務(wù)端,
demo1:基于script標(biāo)簽實(shí)現(xiàn)跨域
舉個(gè)例子:我在http://study.cn/json/jsonp/jsonp_2.html下請(qǐng)求一個(gè)遠(yuǎn)程的js文件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title><script type="text/javascript">var message = function(data) {alert(data[1].title);}; </script><script type="text/javascript" src="http://web.cn/js/message.js"></script> </head> <body> <div id='testdiv'></div> </body> </html>遠(yuǎn)程的message.js文件是
message([{"id":"1", "title":"天津新聞聯(lián)播,雷人搞笑的男主持人"},{"id":"2", "title":"樓市告別富得流油 專家:房?jī)r(jià)下跌是大概率事件"},{"id":"3", "title":"法國(guó)人關(guān)注時(shí)事 八成年輕人每天閱讀新聞"},{"id":"4", "title":"新聞中的歷史,歷史中的新聞"},{"id":"5", "title":"東陽(yáng)新聞20140222"},{"id":"6", "title":"23個(gè)職能部門(mén)要增加新聞發(fā)布頻次"},{"id":"7", "title":"《貴州新聞聯(lián)播》 中國(guó)美麗鄉(xiāng)村"},{"id":"8", "title":"朝韓離散家屬團(tuán)聚首輪活動(dòng)結(jié)束"},{"id":"9", "title":"索契冬奧會(huì)一天曝出兩例興奮劑事件"},{"id":"10", "title":"今天中國(guó)多地仍將出現(xiàn)中度霾"}]);這個(gè)時(shí)候我們得到的相應(yīng)頭是:
這樣就實(shí)現(xiàn)跨域成功了,因?yàn)榉?wù)端返回?cái)?shù)據(jù)時(shí)會(huì)將這個(gè)callback參數(shù)(message)作為函數(shù)名來(lái)包裹住JSON數(shù)據(jù),這樣客戶端就可以隨意定制自己的函數(shù)來(lái)自動(dòng)處理返回?cái)?shù)據(jù)了。
demo2:?基于script標(biāo)簽實(shí)現(xiàn)跨域
讓遠(yuǎn)程js知道它應(yīng)該調(diào)用的本地函數(shù)叫什么名字,只要服務(wù)端提供的js腳本是動(dòng)態(tài)生成的就好了,這樣前臺(tái)只需要傳一個(gè)callback參數(shù)過(guò)去告訴服務(wù)端,我需要XXX代碼,于是服務(wù)端就會(huì)得到相應(yīng)了.
例如 在http://study.cn/json/jsonp/jsonp_3.html頁(yè)面請(qǐng)求?http://192.168.31.137/train/test/jsonpthree
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title><script type="text/javascript">var messagetow = function(data){alert(data);};var url = "http://192.168.31.137/train/test/jsonpthree?callback=messagetow";var script = document.createElement('script'); script.setAttribute('src', url); document.getElementsByTagName('head')[0].appendChild(script); </script> </head> <body> </body> </html>得到的響應(yīng)頭是:
demo3:??基于jquery跨域
那么如何用jquery來(lái)實(shí)現(xiàn)我們的跨域呢???jquery已經(jīng)把跨域封裝到ajax上了,而且封裝得非常的好,使用起來(lái)也特別方便
如果是一般的ajax請(qǐng)求:
$.ajax({url:'http://192.168.31.137/train/test/testjsonp',type : 'get',dataType : 'text',success:function(data){alert(data);},error:function(data){alert(2);} });那么在瀏覽器中會(huì)報(bào)錯(cuò):
jsonp形式的ajax請(qǐng)求:并且通過(guò)get請(qǐng)求的方式傳入?yún)?shù),注意:跨域請(qǐng)求是只能是get請(qǐng)求不能使用post請(qǐng)求
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="./js/jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){var name = 'chenshishuo';var sex = 'man';var address = 'shenzhen';var looks = 'handsome ';$.ajax({type : 'get',url:'http://192.168.31.137/train/test/testjsonp',data : {name : name,sex : sex,address : address,looks : looks,},cache :false,jsonp: "callback",jsonpCallback:"success",dataType : 'jsonp',success:function(data){alert(data);},error:function(data){alert('error');} }); }); </script> </head> <body> <input id='inputtest' value='546' name='inputtest'> <div id='testdiv'></div> </body> </html> jsonp 傳遞給請(qǐng)求處理程序或頁(yè)面的,用以獲得jsonp回調(diào)函數(shù)名的參數(shù)名(默認(rèn)為:callback) jsonpCallback 自定義的jsonp回調(diào)函數(shù)名稱,默認(rèn)為jQuery自動(dòng)生成的隨機(jī)函數(shù)名看看請(qǐng)求頭和相應(yīng)頭吧
請(qǐng)求頭:jquery會(huì)自動(dòng)帶入callback參數(shù),當(dāng)服務(wù)端獲取到這個(gè)參數(shù)后,返回回來(lái).(響應(yīng)頭)
現(xiàn)在是不是明白了跨域的基本原理,和基本的使用方法呢??
上面我們說(shuō)到img中的src可以自動(dòng)調(diào)用遠(yuǎn)程圖片的(這個(gè)比較簡(jiǎn)單我在這里就不說(shuō)了)
還有ifram請(qǐng)求:
基于iframe實(shí)現(xiàn)的跨域要求兩個(gè)域具有aa.xx.com,bb.xx.com 這種特點(diǎn),
也就是兩個(gè)頁(yè)面必須屬于一個(gè)基礎(chǔ)域(例如都是xxx.com),使用同一協(xié)議和同一端口,這樣在兩個(gè)頁(yè)面中同時(shí)添加document.domain,就可以實(shí)現(xiàn)父頁(yè)面調(diào)用子頁(yè)面的函數(shù)
要點(diǎn)就是 :通過(guò)修改document.domain來(lái)跨子域
demo4:?通過(guò)iframe來(lái)跨子域
http://a.study.cn/a.html 請(qǐng)求 http://b.study.cn/b.html
在a.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title><script type="text/javascript">document.domain = 'study.cn';function test() {alert(document.getElementById('a').contentWindow);}</script> </head> <body><iframe id='a' src='http://b.study.cn/b.html' onload='test()'> </body> </html>?在b.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title><script type="text/javascript"> document.domain = 'study.cn'; </script> </head> <body>我是b.study.cn的body </body> </html>運(yùn)行效果截圖:
我們就可以通過(guò)js訪問(wèn)到iframe中的各種屬性和對(duì)象了
如果你想在http://a.study.cn/a.html頁(yè)面中通過(guò)ajax直接請(qǐng)求頁(yè)面http://b.study.cn/b.html,即使你設(shè)置了相同的document.domain也還是不行的.
所以修改document.domain的方法只適用于不同子域的框架(父類與子類)間的交互。
如果想通過(guò)使用ajax的方法去與不同子域間的數(shù)據(jù)交互或者是js調(diào)用,只有兩種方法,一種是使用jsonp的方法外,還有一種是使用iframe來(lái)做一個(gè)代理。
原理就是讓這個(gè) iframe載入一個(gè)與你想要通過(guò)ajax獲取數(shù)據(jù)的目標(biāo)頁(yè)面處在相同的域的頁(yè)面,所以這個(gè)iframe中的頁(yè)面是可以正常使用ajax去獲取你要的數(shù)據(jù) 的,
然后就是通過(guò)我們剛剛講得修改document.domain的方法,讓我們能通過(guò)js完全控制這個(gè)iframe,這樣我們就可以讓iframe去發(fā) 送ajax請(qǐng)求,然后收到的數(shù)據(jù)我們也可以獲得了。
?
上面的所有知識(shí)點(diǎn),應(yīng)該可以解決第一開(kāi)始提出的問(wèn)題了吧.
總結(jié)
以上是生活随笔為你收集整理的关于跨域,以及跨域的几种方式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: 少林寺武僧玩抖音,灵隐寺小编KPI随缘…
 - 下一篇: 国庆