摘自:https://segmentfault.com/a/1190000007935557javascript
1、JSONP的誕生php
首先,由於ajax沒法跨域,而後開發者就有所思考java
其次,開發者發現, <script>標籤的src屬性是能夠跨域的
把跨域服務器寫成 調用本地的函數 ,回調數據回來不就行了?ajax
json恰好被js支持(object)json
調用跨域服務器上動態生成的js格式文件(無論是什麼類型的地址,最終生成的返回值都是一段js代碼)segmentfault
這種獲取遠程數據的方式看起來很是像ajax,但其實並不同
便於客戶端使用數據,逐漸造成了一種非正式傳輸協議,人們把它稱做JSONP。跨域
傳遞一個callback參數給跨域服務端,而後跨域服務端返回數據時會將這個callback參數做爲函數名來包裹住json數據便可。bash
2、老闆,來一斤栗子。
【栗子一】
跨域服務器
文件:remote.js
代碼:服務器
alert('我是遠程文件');
本地app
<script type="text/javascript" src="跨域服務器/remote.js"></script>
這邊作的就是直接引入一個js,頁面將會彈出一個提示窗體,顯示 我是遠程文件。
【栗子二】
跨域服務器
文件:remote.js
代碼:
localHandler({"result":"我是遠程js帶來的數據"});
本地
<script type="text/javascript"> var localHandler = function(data){ alert('我是本地函數,能夠被跨域的remote.js文件調用,遠程js帶來的數據是:' + data.result); }; </script> <script type="text/javascript" src="跨域服務器/remote.js"></script>
這邊作的是
一、本地定義一個函數
二、引入一個js
三、被引入的js裏面,調用這個函數頁面將會彈出一個提示窗體。顯示本地函數被跨域的遠程js調用成功,而且還接收到了 我是遠程js帶來的數據。
新問題出現了:讓遠程js知道它應該調用的本地函數叫什麼名字呢?畢竟是jsonp的服務者都要面對不少服務對象,而這些服務對象各自的本地函數都不相同啊?
【栗子三】
跨域服務端提供的js腳本動態生成,這樣調用者能夠傳一個參數過去告訴跨域服務端「我想要一段調用XXX函數的js代碼,請你返回給我」,因而跨域服務器就能夠按照客戶端的需求來生成js腳本並響應了。
跨域服務器
文件:flightResult.php
代碼:
flightHandler({
"code":"CA1998", "price": 1780, "tickets": 5 });
本地
<script type="text/javascript"> // 獲得航班信息查詢結果後的回調函數 var flightHandler = function(data){ alert('你查詢的航班結果是:票價 ' + data.price + ' 元,' + '餘票 ' + data.tickets + ' 張。'); }; // 提供jsonp服務的url地址(無論是什麼類型的地址,最終生成的返回值都是一段javascript代碼) var url = "跨域服務器/flightResult.php?code=CA1998&callback=flightHandler"; // 建立script標籤,設置其屬性 var script = document.createElement('script'); script.setAttribute('src', url); // 把script標籤加入head,此時調用開始 document.getElementsByTagName('head')[0].appendChild(script); </script>
此次咱們作的是
一、動態建立腳本
二、url中傳遞了一個code參數,服務器去作查詢CA1998次航班的信息,callback參數告訴服務器,個人本地回調函數叫作flightHandler
三、跨域服務端調用這個函數flightHandler 頁面將會彈出一個提示窗體。把票價、餘票以及張數給傳遞回來了。
3、那麼服務器到底作了什麼呢? 說到底,就是拼接字符串。
// 數據 $data = [ "name":"anonymous66", "age":"18", "like":"jianshu" ]; // 接收callback函數名稱 $callback = $_GET['callback']; // 輸出 echo $callback . "(" . json_encode($data) . ")";
4、與AJAX的區別是什麼?
ajax和jsonp本質上是不一樣的東西。
ajax的核心是經過XmlHttpRequest獲取非本頁內容
jsonp的核心則是動態添加<script>標籤來調用服務器提供的js腳本。
5、結語本篇文章是對JSONP的原理掃盲,通常不少開發者會使用殊不知道原理,這在學習和成長的路上不算好事。so,知道jsonp原理,你又能夠加50塊工資了。