1. 程式人生 > >JS跨域呼叫之JSONP--動態Script標籤方式實現跨域

JS跨域呼叫之JSONP--動態Script標籤方式實現跨域

動態Script標籤的方式往往是用來訪問不在同一個域的伺服器內部的資料的。例如, 
當前我的域名:
d1.wwwcomy.com
我需要訪問的資料:
百度翻譯"chair"的結果

由於百度翻譯和我的域名不在一個域名下,所以這個資料通過常規方式是沒辦法獲取的,是被瀏覽器的安全機制所禁止的,解決方法如下: 

首先要知道這個基礎知識: 

引用 Web頁面上凡是擁有"src"這個屬性的標籤都擁有跨域的能力,比如<script>、<img>、<iframe>

所以,最簡單的方法為:我們可以在自己的域名下用iframe引用百度中chair翻譯的頁面(=。=)。 
這個好像比較雷。。那麼如何靈活的自己控制呢? 


這就要用到動態script標籤方式了,JSONP,JSON with Padding,是一個非官方的解決跨域訪問的"協議",採用JSON作為傳輸資料的載體,具體的實現是通過script標籤跨域引用來完成的。 

實現JSONP的前提: 


兩個例子: 
1.最簡單的入門呼叫
我們先使用百度翻譯作為服務端,寫一個客戶端呼叫的HTML例子testCallBack.html: 

Html程式碼  收藏程式碼
  1. <html>  
  2. <head>  
  3. <title>Title</title>  
  4. <meta http-equiv="Content-Type" content
    ="text/html; charset=UTF-8" />  
  5. <script type="text/javascript" language="javascript"  
  6.     src="jquery-1.7.2.js"></script>  
  7. <script type="text/javascript">  
  8.     function abc(re) {  
  9.         alert(re.trans_result[0].src + "翻譯的結果為\"" + re.trans_result[0].dst+"\"");  
  10.     }  
  11. </script
    >  
  12. <script type="text/javascript" language="javascript" src="http://openapi.baidu.com/public/2.0/bmt/translate?client_id=2ALMz6WqUEcsBg4BS91Eppq3&q=chair&from=auto&to=auto&callback=abc"></script>  
  13. </head>  
  14. <body>  
  15. </body>  
  16. </html>  


開啟頁面後發現訪問成功,如果要動態翻譯的話,可以動態的生成這個script標籤。 

2.簡單的動態生成script例子testTag1.html 

Html程式碼  收藏程式碼
  1. <html>  
  2. <head>  
  3. <title>Title</title>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
  5. <script type="text/javascript">  
  6.     function abc(re) {  
  7.         alert(re.trans_result[0].src + "翻譯的結果為\"" + re.trans_result[0].dst+"\"");  
  8.     }  
  9.     function onClick()  
  10.     {  
  11.         var script = document.createElement("script");  
  12.         script.type = "text/javascript";  
  13.         var src = document.getElementById("word").value;  
  14.         script.src = "http://openapi.baidu.com/public/2.0/bmt/translate?client_id=2ALMz6WqUEcsBg4BS91Eppq3&q="+src+"&from=auto&to=auto&callback=abc";  
  15.         document.body.appendChild(script);  
  16.     }  
  17. </script>  
  18. </head>  
  19. <body>  
  20.     <input type="text" value="pen" id="word"/>  
  21.     <input type="button" value="click me!" onclick="onClick()"/>  
  22. </body>  
  23. </html>  

***注意:本例子只是用來演示,真正使用時候請注意script標籤的清除,避免頁面無限制增加script標籤。其他注意事項暫時還沒想到=。=

客戶端程式碼基本是在這個基礎上進行修改,下面來討論一下服務端程式碼,其實服務端程式碼也很簡單,甚至寫個servlet組裝字串生成JSON格式的字元就可以,當然要與客戶端協調好json的格式。 
服務端Servlet生成如下的字串返回來就行了: 
Js程式碼  收藏程式碼
  1. abc({"from":"en","to":"zh","trans_result":[{"src":"chair","dst":"\u6905\u5b50"}]});  

另外要處理callback這個回撥引數,上面百度API介紹裡面本來沒有callback引數的介紹,後來我隨意打了一個竟然人家還實現了。 

回顧一下實際上流程很簡單: 
  • 1.客戶端根據條件生成一個url,包含請求資料(如"chair")和回撥函式名(如"abc")
  • 2.客戶端寫好回撥函式function abc(re){}
  • 3.服務端接收此請求,生成json資料,並根據回撥函式名,動態生成類似 abc(json("chair"))這樣的資料返回給客戶端。
  • 4.客戶端執行abc(json("chair"))