1. 程式人生 > >Javascript中事件機制詳解

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的核心則是動態新增