利用 jsonp 進行 Javascript 的跨域數據訪問

http://chinazblz.blog.163.com/blog/static/93939173201042485426995/

 令附註iframe跨域調用傳值:http://www.blueidea.com/tech/web/2009/6932.asp

 

一、基礎知識

  1、什麼是 JSON:JavaScript Object Notation (JSON) 是一種輕量級、基於文本、語言無關的數據交換格式。它是從 ECMAScript 語言標準衍生而來的。JSON爲輕便的表示結構化數據,定義了一小套格式化規則。以下是一個 JSON 對象的例子:

{
  
"Image": {
  
"Width": 800,
  
"Height": 600,
  
"Title": "View from 15th Floor",
  
"Thumbnail": {
  
"Url": "http://www.example.com/image/481989943",
  
"Height": 125,
  
"Width": "100"
  
},
  
"IDs": [116, 943, 234, 38793]
  
}
}

  2、什麼是 JSONP:JSONP(JSON with Padding)是一個非官方的協議,它允許在服務器端集成 Script tags 返回至客戶端,通過 Javascript callback 的形式實現跨域訪問(這僅僅是 JSONP 簡單的實現形式)。

二、JSONP 的原理

  首先說明一下,想要使用 JSONP 來進行跨域訪問,必須服務器端支持,原因後面再解釋。和 AJAX 一樣,JSONP 實際上也是早已存在,只是說法相對比較新穎(貌似也出來很久了,額…),而且所有做網頁開發肯定都用過。爲什麼這麼說?應爲它用到的只是所有 HTML 元素中一個簡單的 script 元素。看到這是不是覺得越發奇怪了?沒關係,繼續看下去就會茅廁(塞)頓開的,嘿嘿~來看個例子吧:
demo.html 文件

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Demo</title>
<script type="text/javascript">
function say(words) {
   alert(words);
}
</script>
</head>
<body>
<script type="text/javascript" src="demo.js"></script>
</body>
</html>

demo.js 文件

say("Hello, everyone!");

  運行 demo.html 文件後,是不是看到寫着“Hello, everyone!”的警告框了?你可能會覺得這個例子很簡單,沒什麼了不起的,甚至會在想:這和 JSONP 有關係嗎?那麼,我可以很肯定的告訴你:有關係!而且,這個例子實際上就是 JSONP 的原型!你也許會想到,JSONP 不是訪問遠程數據的嗎?對,試想一下,如果 demo.js 文件在其它域的服務器上呢?結果會不會出現問題?我也可以很負責的告訴你:不會!你可以將上面例子中的 demo.js 更改爲:http://demo.hpyer.cn/php/jsonp.php?callback=say 再試一下。
  現在,聰明的你應該已經明白 JSONP 到底是怎麼回事了,那麼,再來解釋一下本節開頭第一句話吧。看過 demo.js 文件的內容,應該知道,其只是對一個函數(通常稱之爲:回調函數)的調用,而需要交互的數據則通過參數形勢進行返回。所以通過 JSONP 訪問的服務器需要提供一個可以設置回調函數名的接口,就像 http://demo.hpyer.cn/php/jsonp.php?callback=say 中的 callback,所以,綜上所述 JSONP 是需要服務器端的支持的。附上 jsonp.php 的源碼:

<?php
$type = isset($_GET['type']) ? $_GET['type'] : '';
$callback = isset($_GET['callback']) ? $_GET['callback'] : '';
$json = '';

if ($type == 'json') {
  
$json = '{
   "Image": {
   "Width": 800,
   "Height": 600,
   "Title": "View from 15th Floor",
   "Thumbnail": {
   "Url": "http://www.example.com/image/481989943",
   "Height": 125,
   "Width": "100"
   },
   "IDs": [116, 943, 234, 38793]
   }
   }
';
} else {
  
$json = '"Hello, everyone!"';
}

if (!empty($callback)) {
  
$json = $callback . '(' . $json . ')';
}

echo $json;
?>

三、jQuery 中的應用

  自 1.2 版本起,jQuery 加入了對 JSONP 的支持。我們可以很容易的利用 $.getJSON() 方法(或者其它基於 $.ajax() 的方法),來跨域加載 JSON 數據。來個例子吧:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Demo</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
function do_jsonp() {
   $.getJSON("http://demo.hpyer.cn/php/jsonp.php?type=json&callback=?",
   function(data) {
   $('#result').val('data.Image.IDs: ' + data.Image.IDs);
   });
}
</script>
</head>
<body>
<a href="javascript:do_jsonp();">Click me</a><br />
<textarea id="result" cols="50" rows="5"></textarea>
</body>
</html>

  你可能注意到上面的例子中,url 被寫成了 http://demo.hpyer.cn/php/jsonp.php?type=json&callback=?,需要說明的是,這個問號會被 jQuery 自動替換爲回調函數的函數名(如果是一個匿名函數,jQuery 會自動生成一個帶時間戳的函數名)。

四、小結

  通過本文的描述,相信你對於 JSONP 有了一個比較直觀的瞭解,Hpyer 也相信,你也肯定可以舉一反三的寫出屬於你自己的代碼。其實,JSONP 的實現方法並不是只有回調函數一種,還有其它方式,例如將數據賦值給一個變量等。在 Web 2.0 的總體趨勢之下,JS 顯得越來越重要,併成了許多網頁製作者所必學的一種腳本,所以,盡情的去體會 JS 帶來的樂趣吧,Enjoy it!

原文轉自:http://hpyer.cn/visit-remote-data-with-jsonp-in-javascript.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章