前兩天被問到ajax跨域如何解決,還真被問住了,光知道有個甚么jsonp,迷迷糊糊的沒有說上來。抱著有問題必須解決的態(tài)度,我看了許多資料,原來如此。。。
為什么1直知道jsonp,但1直迷迷糊糊的不明白呢?――網上那些介紹資料都寫的太復雜了!
我是能多簡單就多簡單,爭取讓你10分鐘看完!
ajax之所以需要“跨域”,罪魁罪魁就是閱讀器的同源策略。即,1個頁面的ajax只能獲得這個頁面相同源或相同域的數據。
如何叫“同源”或“同域”呢?――協(xié)議、域名、端口號都必須相同。例如:
http://google.com 和 https://google.com 不同,由于協(xié)議不同;
http://localhost:8080 和 http://localhost:1000 不同,由于端口不同;
http://localhost:8080 和 https://google.com 不同,協(xié)議、域名、端口號都不同,根本不是1家的。
根據同源策略,我自己做的1個網頁 http://localhost:8080/test.html 就沒法通過ajax直接獲得 http://google.com 的數據。
例如,我用ajax去訪問1個不同域的頁面,毛病結果是這樣的:
大家想一想,這樣其實也有道理。如果沒有同源策略,你我都可以隨意通過ajax直接獲得其他網站的信息,這還穩(wěn)定套了。。。我自己做1個搜索界面,搜索時直接用ajax從百度獲得數據,那不成了小偷了。。。
但是跨域訪問是少不了的,mail.163.com 的網頁可能需要從 news.163.com 域下獲得新聞信息,那怎樣辦?――開始我們的跨域之旅。(固然用iframe也能夠實現)
http://www.vxbq.cn/Internet/的許多網站之間圖片相互盜鏈,A網站網頁的img.src直接鏈接到B網站的圖片地址,這是常有的事兒。說到“盜鏈”,大家第1想到的多是如何去避免盜鏈,今兒咱不管那個。
你再想一想“盜鏈”和“同源策略”這兩個詞之間有甚么關系?――對,矛盾!既然都“同源策略”了,怎樣還能“盜鏈”呢?
世間萬物都有矛盾,有矛盾了照樣可以和諧共處,其實不1定非要你死我活。
重點:<img>的src(獲得圖片),<link>的href(獲得css),<script>的src(獲得javascript)這3個都不符合同源策略,它們可以跨域獲得數據。因此,你可以直接從1些cdn上獲得jQuery,并且你網站上的圖片也隨時可能被他人盜用,所有最好加上水印!
而我們今天的主角――jsonp――就是由于<script>的src不符合同源策略而來的。
例如,域名 a.com 下有1個 a.com/test.html 網頁,域名 b.com 下有1個 b.com/data.html 網頁和 b.com/alert.js 文件。
引導第1步:簡單援用js
編寫 b.com/alert.js 以下:
對 a.com/test.html 編寫以下代碼:
運行 a.com/test.html,結果很明顯,就是彈出 【123】 。
引導第2步:援用js返回數據
將 b.com/alert.js 修改成:
將 a.com/test.html 修改成:
運行 a.com/test.html,結果是彈出【 100px 】,這個應當也沒有甚么疑問。
引導第3步:已跨域成功!
第2步中,如果data――即100――是我要跨域在b.com下獲得的1個數據,那末我們這不就是已實現跨域要求了嗎!!!
把這個進程再清晰的捋1遍:
引導第4步:援用html格式
<script>的src不1定僅僅指向javascript文件,可以指向任何地址。例如:
將 a.com/test.html 修改成:
將 b.com/data.html 編寫為:(注意,data.html中就寫以下1行代碼,多了不寫)
運行 a.com/test.html ,結果仍然是【 100px 】
其中,“100”就是我們要跨域要求的數據。
引導第5步:動態(tài)數據
如果要要求的數據是動態(tài)的,那就要在動態(tài)頁面中編寫。
那末我們就讓 a.com/test.html 去調用1個動態(tài)的aspx頁面:
大家注意,我們在 src 地址中增加了“?callback=myFn”,意思是把顯示數據的函數也動態(tài)傳過去了,而第2步、第4步都是靜態(tài)的寫在被調用的文件中的。
至于callback參數后臺如何接收,如何使用,請接著看:
在 b.com 下增加1個 b.com/data.aspx 頁面,后臺代碼以下:
代碼很簡單,獲得callback參數,然后組成1個函數的情勢返回。如果“b.com/data.aspx?callback=myFn”調用的話,那末返回的就是" myFn(1024) "。
返回的數據變成動態(tài)的了(“1024”),前端頁面用于顯示數據的函數也編程了動態(tài)的了(“callback=myFn”),但是歸根結柢,情勢還是1樣的。
引導第6步:調用封裝
a.com/test.html 中,僅唯一1個<script>靜靜的躺在那里,履行1次以后,就沒有作用了。
而實際情況是,a.com/test.html 中,可能隨著用戶的操作產生若干次的調用。怎樣辦?――動態(tài)增加唄。
以上層層描寫的就是JSONP,你沒必要去記住它的定義,看明白了上述文字,就全能理解。
重點在于:同源策略 + <script>的src不屬于同源策略 + 通過<script>的src指向的文件返回http://www.vxbq.cn/server/端數據。
ok,就這些!
-------------------------------------------------------------------------------------------------------------
歡迎關注我的微博。
也歡迎關注我的其他教程:
《從設計到模式》《深入理解javascript原型和閉包系列》《微軟petshop4.0源碼解讀視頻》《json2.js源碼解讀視頻》