Javascript中事件機制詳解
起JSON和JSONP,想必很多人一開始會認為這兩者是有一定的聯絡的,然而JSON和JSONP雖然只有一個字母的差別,但其實他們根本不是一回事,這讓我想起一句話“JSON和JSONP的區別就是雷鋒和雷鋒塔的區別”,那麼雷鋒和雷鋒塔的有什麼樣的區別呢?當然是沒有區別!!!
什麼是JSON
簡單來說,JSON是一種基於文字的資料交換方式,或者叫做資料描述格式;
JSON的優點:
1、基於純文字,跨平臺傳遞極其簡單;
2、JavaScript原生支援,後臺語言幾乎全部支援;
3、輕量級資料格式,佔用字元數量極少,特別適合網際網路傳遞;
4、可讀性較強,雖然比不上XML那麼一目瞭然,但在合理的依次縮排之後還是很容易識別的;
5、容易編寫和解析,當然前提是你要知道資料結構;
JSON的格式:
1、JSON只有兩種資料型別描述符,大括號{}和方括號[],其餘英文冒號:是對映符,英文逗號,是分隔符,英文雙引號”“是定義符。
2、大括號{}用來描述一組“不同型別的無序鍵值對集合”,方括號[]用來描述一組“相同型別的有序資料集合”。
3、上述兩種集合中若有多個子項,則通過英文逗號,進行分隔。
4、鍵值對以英文冒號:進行分隔,並且建議鍵名都加上英文雙引號”“,以便於不同語言的解析。
5、JSON內部常用資料型別無非就是字串、數字、布林、日期、null 這麼幾個,字串必須用雙引號引起來,其餘的都不用。
JSON例項:
// 描述一次會議
var conference = {
"Conference" : "Future Marketing",
"Date": "2017-6-1",
"Address": "Beijing",
"Members":
[
{
"Name": "Bob",
"Age": 32,
"Company": "IBM",
"Engineer": true
},
{
"Name": "John",
"Age": 20,
"Company" : "Oracle",
"Engineer": false
},
{
"Name": "Henry",
"Age": 45,
"Company": "Microsoft",
"Engineer": false
}
]
}
// 讀取參會者Henry是否工程師
var henryIsAnEngineer = conference.Members[2].Engineer;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
什麼是JSONP?
JSONP的產生
1、一個眾所周知的問題,Ajax直接請求普通檔案存在跨域無許可權訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一律不準;
2、不過我們又發現,Web頁面上呼叫js檔案時則不受是否跨域的影響(不僅如此,我們還發現凡是擁有”src”這個屬性的標籤都擁有跨域的能力,比如
alert('我是遠端檔案');
- 1
- 1
本地伺服器localserver.com下有個jsonp.html頁面程式碼如下:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
毫無疑問,頁面將會彈出一個提示窗體,顯示跨域呼叫成功。
2、現在我們在jsonp.html頁面定義一個函式,然後在遠端remote.js中傳入資料進行呼叫。
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
var localHandler = function(data){
alert('我是本地函式,可以被跨域的remote.js檔案呼叫,遠端js帶來的資料是:' + data.result);
};
</script>
<script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
remote.js檔案程式碼如下:
localHandler({"result":"我是遠端js帶來的資料"});
- 1
- 1
檢視結果,頁面成功彈出提示視窗,顯示本地函式被跨域的遠端js呼叫成功,並且還接收到了遠端js帶來的資料。很欣喜,跨域遠端獲取資料的目的基本實現了,但是又一個問題出現了,我怎麼讓遠端js知道它應該呼叫的本地函式叫什麼名字呢?
3、只要服務端提供的js指令碼是動態生成的就行了唄,這樣呼叫者可以傳一個引數過去告訴服務端“我想要一段呼叫XXX函式的js程式碼,請你返回給我,於是伺服器就可以按照客戶端的需求來生成js指令碼並響應了。
看jsonp.html頁面的程式碼:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
// 得到航班資訊查詢結果後的回撥函式
var flightHandler = function(data){
alert('你查詢的航班結果是:票價 ' + data.price + ' 元,' + '餘票 ' + data.tickets + ' 張。');
};
// 提供jsonp服務的url地址(不管是什麼型別的地址,最終生成的返回值都是一段javascript程式碼)
var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
// 建立script標籤,設定其屬性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script標籤加入head,此時呼叫開始
document.getElementsByTagName('head')[0].appendChild(script);
</script>
</head>
<body>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
這次的程式碼實現動態查詢,而這也正是jsonp客戶端實現的核心部分,我們看到呼叫的url中傳遞了一個code引數,告訴伺服器我要查的是CA1998次航班的資訊,而callback引數則告訴伺服器,我的本地回撥函式叫做flightHandler,所以請把查詢結果傳入這個函式中進行呼叫。
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
我們看到,傳遞給flightHandler函式的是一個json,它描述了航班的基本資訊。執行一下頁面,成功彈出提示視窗,jsonp的執行全過程順利完成!
4、再給一段jQuery使用jsonp的程式碼(我們依然沿用上面那個航班資訊查詢的例子,假定返回jsonp結果不變):
<!DOCTYPE html>
<html>
<head>
<title>Untitled Page</title>
<script type="text/javascript" src=jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
$.ajax({
type: "get",
async: false,
url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
dataType: "jsonp",
jsonp: "callback",//傳遞給請求處理程式或頁面的,用以獲得jsonp回撥函式名的引數名(一般預設為:callback)
jsonpCallback:"flightHandler",//自定義的jsonp回撥函式名稱,預設為jQuery自動生成的隨機函式名,也可以寫"?",jQuery會自動為你處理資料
success: function(json){
alert('您查詢到航班資訊:票價: ' + json.price + ' 元,餘票: ' + json.tickets + ' 張。');
},
error: function(){
alert('fail');
}
});
});
</script>
</head>
<body>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
AJAX與JSONP的異同
1、ajax和jsonp這兩種技術在呼叫方式上“看起來”很像,目的也一樣,都是請求一個url,然後把伺服器返回的資料進行處理,因此jquery和ext等框架都把jsonp作為ajax的一種形式進行了封裝;
2、但ajax和jsonp其實本質上是不同的東西。ajax的核心是通過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態新增