因爲瀏覽器中的同源策略,不一樣的域名,不一樣的協議,甚至不一樣的端口都沒法請求數據。所以出現了瀏覽器跨域請求數據問題。javascript
Jsonp是解決跨域問題的一個很是流行的方法。php
JSONP(JSON with Padding),其實就是被包裹在函數調用中的JSON。java
callback({"name": "Kate"});express
經過script標籤進行跨域操做,載入的請求js文件中的內容會執行咱們在url中指定的函數,而且,傳入的參數,就是咱們請求的數據。json
1 <script> 2 // 先定義咱們將要處理數據的函數 3 function myFun(data) { 4 console.log(data); 5 } 6 </script> 7 8 <!-- 咱們使用script標籤來進行跨域請求,並使用callback標明咱們將要處理數據的函數 --> 9 <!-- 此處我使用的是聚合數據的數據資源 --> 10 <script src="http://v.juhe.cn/expressonline/getCarriers.php?key=6a1038e454e6d4b25457b911c8d9b815&callback=myFun"></script>
最終顯示爲:api
咱們成功獲取不一樣域名下的資源。並經過自定義的myFun函數將得到的數據打印出來了。跨域
在使用jsonp過程當中,可能由於請求數據的API要求不一樣,咱們須要構建本身的jsonp方法,下面咱們簡單介紹一種相似jQuery中jsonp的實現。瀏覽器
首先,咱們建立一個以jQuery開頭的隨機的函數名,並將其掛載到window對象中。在這個函數中,咱們調用咱們傳入的回調函數處理數據。app
而後,咱們開始處理傳入的url,此時,咱們規定傳入的url不帶有callback查詢字符串,方便咱們根據不一樣的API要求傳入對應的參數。框架
最後,咱們建立script標籤,並指定其src爲前面處理好的url,將其添加到文檔中,便可獲取數據。
1 <script> 2 // 自定義框架名稱myFrame 3 var myFrame = {}; 4 5 // 添加jsonp方法 6 myFrame.jsonp = function(url, callback) { 7 // 生成隨機函數名 8 var cbname = 'jQuery' + new Date().getTime(); 9 10 // 把cbname做爲函數名掛載到window對象上 11 window[cbname] = function(data) { 12 // 調用傳入的回調函數處理數據 13 callback(data); 14 15 // 調用數據以後,刪除建立的script標籤 16 // 放置script標籤無限增加 17 document.body.removeChild(script); 18 } 19 20 // 拼接url,將callback添加到url中, 21 // 如:http://api.douban.com/v2/movie/in_theaters?callback=;jQuery1487687886270 22 url += url.indexOf('?') == -1 ? '?' : '&'; 23 url += 'callback=' + cbname; 24 25 // 建立script標籤 26 var script = document.createElement('script'); 27 // 添加script標籤屬性 28 script.src = url; 29 script.type = 'text/javascript'; 30 31 // 將script標籤添加到文檔中,此時開始請求咱們的數據 32 document.body.appendChild(script); 33 34 } 35 36 // 調用框架中的方法,此時使用豆瓣API 37 myFrame.jsonp('http://api.douban.com/v2/movie/in_theaters', function(data) { 38 console.log(data); 39 }); 40 </script>
成功請求到數據:
script標籤請求到的內容: