美麗涵涵童裝店--說我博客名字,給你們打折!
          隨筆 - 82  文章 - 266  trackbacks - 0
          <2014年10月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678


          點(diǎn)擊這里給楊愛友發(fā)消息
          美麗涵涵童裝店
          說我博客名字,給你們打折!

          常用鏈接

          留言簿(6)

          隨筆分類

          隨筆檔案

          文章檔案

          好友的BLOG

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          轉(zhuǎn)載自【http://justcoding.iteye.com/blog/1366102】
          Asynchronous JavaScript and XML (Ajax ) 是驅(qū)動(dòng)新一代 Web 站點(diǎn)(流行術(shù)語為 Web 2.0 站點(diǎn))的關(guān)鍵技術(shù)。Ajax 允許在不干擾 Web 應(yīng)用程序的顯示和行為的情況下在后臺(tái)進(jìn)行數(shù)據(jù)檢索。使用 XMLHttpRequest 函數(shù)獲取數(shù)據(jù),它是一種 API,允許客戶端 JavaScript 通過 HTTP 連接到遠(yuǎn)程服務(wù)器。Ajax 也是許多 mashup 的驅(qū)動(dòng)力,它可將來自多個(gè)地方的內(nèi)容集成為單一 Web 應(yīng)用程序。

           

          不過,由于受到瀏覽器的限制,該方法不允許跨域通信。如果嘗試從不同的域請(qǐng)求數(shù)據(jù),會(huì)出現(xiàn)安全錯(cuò)誤。如果能控制數(shù) 據(jù)駐留的遠(yuǎn)程服務(wù)器并且每個(gè)請(qǐng)求都前往同一域,就可以避免這些安全錯(cuò)誤。但是,如果僅停留在自己的服務(wù)器上,Web 應(yīng)用程序還有什么用處呢?如果需要從多個(gè)第三方服務(wù)器收集數(shù)據(jù)時(shí),又該怎么辦?

           

          理解同源策略限制

          同源策略阻止從一個(gè)域上加載的腳本獲取或操作另一個(gè)域上的文檔屬性。也就是說,受到請(qǐng)求的 URL 的域必須與當(dāng)前 Web 頁面的域相同。這意味著瀏覽器隔離來自不同源的內(nèi)容,以防止它們之間的操作。這個(gè)瀏覽器策略很舊,從 Netscape Navigator 2.0 版本開始就存在。

           

          克服該限制的一個(gè)相對(duì)簡單的方法是讓 Web 頁面向它源自的 Web 服務(wù)器請(qǐng)求數(shù)據(jù),并且讓 Web 服務(wù)器像代理一樣將請(qǐng)求轉(zhuǎn)發(fā)給真正的第三方服務(wù)器。盡管該技術(shù)獲得了普遍使用,但它是不可伸縮的。另一種方式是使用框架要素在當(dāng)前 Web 頁面中創(chuàng)建新區(qū)域,并且使用 GET 請(qǐng)求獲取任何第三方資源。不過,獲取資源后,框架中的內(nèi)容會(huì)受到同源策略的限制。

           

          克服該限制更理想方法是在 Web 頁面中插入動(dòng)態(tài)腳本元素,該頁面源指向其他域中的服務(wù) URL 并且在自身腳本中獲取數(shù)據(jù)。腳本加載時(shí)它開始執(zhí)行。該方法是可行的,因?yàn)橥床呗圆蛔柚箘?dòng)態(tài)腳本插入,并且將腳本看作是從提供 Web 頁面的域上加載的。但如果該腳本嘗試從另一個(gè)域上加載文檔,就不會(huì)成功。幸運(yùn)的是,通過添加 JavaScript Object Notation (JSON) 可以改進(jìn)該技術(shù)。

          1、什么是JSONP


          要了解JSONP,不得不提一下JSON,那么什么是JSON ?

          JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.

          JSONP(JSON with Padding)是一個(gè)非官方的協(xié)議,它允許在服務(wù)器端集成Script tags返回至客戶端,通過javascript callback的形式實(shí)現(xiàn)跨域訪問(這僅僅是JSONP簡單的實(shí)現(xiàn)形式)。

           

          2、JSONP有什么用?

          由于同源策略的限制,XmlHttpRequest只允許請(qǐng)求當(dāng)前源(域名、協(xié)議、端口)的資源,為了實(shí)現(xiàn)跨域請(qǐng)求,可以通過script標(biāo)簽實(shí)現(xiàn)跨域請(qǐng)求,然后在服務(wù)端輸出JSON數(shù)據(jù)并執(zhí)行回調(diào)函數(shù),從而解決了跨域的數(shù)據(jù)請(qǐng)求。

           

          3、如何使用JSONP?

          下邊這一DEMO實(shí)際上是JSONP的簡單表現(xiàn)形式,在客戶端聲明回調(diào)函數(shù)之后,客戶端通過script標(biāo)簽向服務(wù)器跨域請(qǐng)求數(shù)據(jù),然后服務(wù)端返回相應(yīng)的數(shù)據(jù)并動(dòng)態(tài)執(zhí)行回調(diào)函數(shù)。

           

          HTML代碼 (任一 ):

           

          Html代碼  收藏代碼
          1. <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />  
          2. <script type="text/javascript">  
          3.     function jsonpCallback(result) {  
          4.         //alert(result);  
          5.         for(var i in result) {  
          6.             alert(i+":"+result[i]);//循環(huán)輸出a:1,b:2,etc.  
          7.         }  
          8.     }  
          9.     var JSONP=document.createElement("script");  
          10.     JSONP.type="text/javascript";  
          11.     JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";  
          12.     document.getElementsByTagName("head")[0].appendChild(JSONP);  
          13. </script>  
           

          或者

           

          Html代碼  收藏代碼
          1. <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />  
          2. <script type="text/javascript">  
          3.     function jsonpCallback(result) {  
          4.         alert(result.a);  
          5.         alert(result.b);  
          6.         alert(result.c);  
          7.         for(var i in result) {  
          8.             alert(i+":"+result[i]);//循環(huán)輸出a:1,b:2,etc.  
          9.         }  
          10.     }  
          11. </script>  
          12. <script type="text/javascript" src="http://crossdomain.com/services.php?callback=jsonpCallback"></script>  

           

          JavaScript的鏈接,必須在function的下面。

           

          服務(wù)端PHP代碼 (services.php):

           

          Php代碼  收藏代碼
          1. <?php  
          2.   
          3. //服務(wù)端返回JSON數(shù)據(jù)  
          4. $arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);  
          5. $result=json_encode($arr);  
          6. //echo $_GET['callback'].'("Hello,World!")';  
          7. //echo $_GET['callback']."($result)";  
          8. //動(dòng)態(tài)執(zhí)行回調(diào)函數(shù)  
          9. $callback=$_GET['callback'];  
          10. echo $callback."($result)";  
           

          如果將上述JS客戶端代碼用jQuery的方法來實(shí)現(xiàn),也非常簡單。

           

          $.getJSON
          $.ajax
          $.get

           

          客戶端JS代碼在jQuery中的實(shí)現(xiàn)方式1:

           

          Js代碼  收藏代碼
          1. <script type="text/javascript" src="jquery.js"></script>  
          2. <script type="text/javascript">  
          3.     $.getJSON("http://crossdomain.com/services.php?callback=?",  
          4.     function(result) {  
          5.         for(var i in result) {  
          6.             alert(i+":"+result[i]);//循環(huán)輸出a:1,b:2,etc.  
          7.         }  
          8.     });  
          9. </script>  
           

          客戶端JS代碼在jQuery中的實(shí)現(xiàn)方式2:

           

          Js代碼  收藏代碼
          1. <script type="text/javascript" src="jquery.js"></script>  
          2. <script type="text/javascript">  
          3.     $.ajax({  
          4.         url:"http://crossdomain.com/services.php",  
          5.         dataType:'jsonp',  
          6.         data:'',  
          7.         jsonp:'callback',  
          8.         success:function(result) {  
          9.             for(var i in result) {  
          10.                 alert(i+":"+result[i]);//循環(huán)輸出a:1,b:2,etc.  
          11.             }  
          12.         },  
          13.         timeout:3000  
          14.     });  
          15. </script>  
           

          客戶端JS代碼在jQuery中的實(shí)現(xiàn)方式3:

           

          Js代碼  收藏代碼
          1. <script type="text/javascript" src="jquery.js"></script>  
          2. <script type="text/javascript">  
          3.     $.get('http://crossdomain.com/services.php?callback=?', {name: encodeURIComponent('tester')}, function (json) { for(var i in json) alert(i+":"+json[i]); }, 'jsonp');  
          4. </script>  
           

          其中 jsonCallback 是客戶端注冊(cè)的,獲取 跨域服務(wù)器 上的json數(shù)據(jù) 后,回調(diào)的函數(shù)。
          http://crossdomain.com/services.php?callback=jsonpCallback
          這個(gè) url 是跨域服務(wù) 器取 json 數(shù)據(jù)的接口,參數(shù)為回調(diào)函數(shù)的名字,返回的格式為

           

          Js代碼  收藏代碼
          1. jsonpCallback({msg:'this is json data'})  
           

          Jsonp原理: 
          首先在客戶端注冊(cè)一個(gè)callback, 然后把callback的名字傳給服務(wù)器。

          此時(shí),服務(wù)器先生成 json 數(shù)據(jù)。
          然后以 javascript 語法的方式,生成一個(gè)function , function 名字就是傳遞上來的參數(shù) jsonp.

          最后將 json 數(shù)據(jù)直接以入?yún)⒌姆绞剑胖玫?function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端。

          客戶端瀏覽器,解析script標(biāo)簽,并執(zhí)行返回的 javascript 文檔,此時(shí)數(shù)據(jù)作為參數(shù),傳入到了客戶端預(yù)先定義好的 callback 函數(shù)里.(動(dòng)態(tài)執(zhí)行回調(diào)函數(shù))


          使用JSON的優(yōu)點(diǎn)在于:

          • 比XML輕了很多,沒有那么多冗余的東西。
          • JSON也是具有很好的可讀性的,但是通常返回的都是壓縮過后的。不像XML這樣的瀏覽器可以直接顯示,瀏覽器對(duì)于JSON的格式化的顯示就需要借助一些插件了。
          • 在JavaScript中處理JSON很簡單。
          • 其他語言例如PHP對(duì)于JSON的支持也不錯(cuò)。

          JSON也有一些劣勢:

          • JSON在服務(wù)端語言的支持不像XML那么廣泛,不過JSON.org上提供很多語言的庫。
          • 如果你使用eval()來解析的話,會(huì)容易出現(xiàn)安全問題。

          盡管如此,JSON的優(yōu)點(diǎn)還是很明顯的。他是Ajax數(shù)據(jù)交互的很理想的數(shù)據(jù)格式。

           

          主要提示:

          JSONP 是構(gòu)建 mashup 的強(qiáng)大技術(shù),但不幸的是,它并不是所有跨域通信需求的萬靈藥。它有一些缺陷,在提交開發(fā)資源之前必須認(rèn)真考慮它們。

           

          第一,也是最重要的一點(diǎn),沒有關(guān)于 JSONP 調(diào)用的錯(cuò)誤處理。如果動(dòng)態(tài)腳本插入有效,就執(zhí)行調(diào)用;如果無效,就靜默失敗。失敗是沒有任何提示的。例如,不能從服務(wù)器捕捉到 404 錯(cuò)誤,也不能取消或重新開始請(qǐng)求。不過,等待一段時(shí)間還沒有響應(yīng)的話,就不用理它了。(未來的 jQuery 版本可能有終止 JSONP 請(qǐng)求的特性)。

           

          JSONP 的另一個(gè)主要缺陷是被不信任的服務(wù)使用時(shí)會(huì)很危險(xiǎn)。因?yàn)?JSONP 服務(wù)返回打包在函數(shù)調(diào)用中的 JSON 響應(yīng),而函數(shù)調(diào)用是由瀏覽器執(zhí)行的,這使宿主 Web 應(yīng)用程序更容易受到各類攻擊。如果打算使用 JSONP 服務(wù),了解它能造成的威脅非常重要。

          posted on 2014-10-29 14:57 楊愛友 閱讀(9384) 評(píng)論(5)  編輯  收藏

          FeedBack:
          # AJAX 跨域請(qǐng)求 2014-10-29 17:07 香港服務(wù)器
          AJAX 跨域請(qǐng)求 - JSONP獲取JSON數(shù)據(jù),這個(gè)真的能順利實(shí)現(xiàn)嗎?太神奇了。

          獨(dú)立ip主機(jī)終身3.8折,轉(zhuǎn)發(fā)活動(dòng)的送wifi額,沒wifi的速度轉(zhuǎn)發(fā)喲。。。。。。。。。。。。  回復(fù)  更多評(píng)論
            
          # re: AJAX 跨域請(qǐng)求 - JSONP獲取JSON數(shù)據(jù) 2014-10-29 18:08 楊愛友
          真的能實(shí)現(xiàn),剛做項(xiàng)目已經(jīng)用上了。  回復(fù)  更多評(píng)論
            
          # re: AJAX 跨域請(qǐng)求 - JSONP獲取JSON數(shù)據(jù) 2014-10-30 16:12 寧波倉儲(chǔ)籠
          有一部分沒看懂  回復(fù)  更多評(píng)論
            
          # re: AJAX 跨域請(qǐng)求 - JSONP獲取JSON數(shù)據(jù) 2014-11-02 15:21 網(wǎng)絡(luò)營銷技巧
          要深入研究研究  回復(fù)  更多評(píng)論
            
          # re: AJAX 跨域請(qǐng)求 - JSONP獲取JSON數(shù)據(jù) 2015-02-02 09:44 skyishero
          那個(gè)是異步的  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          美麗涵涵童裝店
          親,說我博客名字,給你們打折!
          主站蜘蛛池模板: 读书| 龙门县| 新蔡县| 九龙坡区| 宁安市| 体育| 韶关市| 武义县| 阿拉尔市| 金沙县| 龙井市| 兴宁市| 千阳县| 噶尔县| 灵川县| 林周县| 万宁市| 红河县| 老河口市| 望谟县| 平顶山市| 六安市| 轮台县| 塘沽区| 甘肃省| 辉县市| 固原市| 水城县| 嘉善县| 砚山县| 浙江省| 北京市| 长子县| 中西区| 金湖县| 白水县| 中卫市| 乐东| 肇州县| 鄂托克旗| 华安县|