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 文件
<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 文件
運行 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 的源碼:
$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 數據。來個例子吧:
<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