JQuery1.2後getJSON方法支持跨域讀取json數據,原理是利用一個叫作jsonp的概念。固然,究其本質仍是經過script標籤動態加載js,彷佛這是實現真正跨域的惟一方法。javascript
getJSON的用法JQuery手冊已經寫得很詳細,參考手冊就能夠了,很簡單。須要指出的一點是getJSON利用的jsonp須要客戶端與服務端做出配合。php
- 客戶端傳遞的URL裏要包含callback變量,以形如callback=?的形式結尾。(jquery會隨機生成一個字符串替換?傳遞給服務端)
- 服務端獲取客戶端傳遞的callback的值callbackValue,和須要傳遞的json字符串構成 callbackValue.’(’.json.’)'傳回給客戶端(示例爲php字符串鏈接方式,其餘語言相似)
不出意外的話應該已經能夠跨域讀取了。
同時輸出json數據時候{以前的是(html
Ajax的應用中,因爲安全的問題,瀏覽器默認是不支持跨域調用的。傳統解決的方法,包括:(參考http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/)java
-
Local proxy:
-
Needs infrastructure (can't run a serverless client) and you get double-taxed on bandwidth and latency (remote - proxy - client).
-
Flash:
-
Remote host needs to deploy a crossdomain.xml file, Flash is relatively proprietary and opaque to use, requires learning a one-off moving target programming langage.
-
Script tag:
-
Difficult to know when the content is available, no standard methodology, can be considered a "security risk".
以上方法都各有缺陷,都不是很好多解決方案。後來出現了一種叫JSON with Padding 的技術,簡稱 JSONP .(原理參考http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/),應 用JSONP能夠實現JSON數據的跨域調用。很是的幸運,JQuery1.2之後支持JSONP的應用。下面側重說明在JQuery中,Json的跨域調用。python
應用JSONP實現Json數據跨域調用,須要服務器端與客戶端的合做完成。引用Jquery官方的例子,客戶端掉用以下:jquery
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?",
function(data){
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#images");
if ( i == 3 ) return false;
});
});
注意這裏調用的地址中jsoncallback=?是關鍵的所在!其中,符號會被Query自動替換成其餘的回調方法的名稱,具體過程和原理咱們這裏不理 會。咱們關心的是jsoncallback=?起什麼做用了?原來jsoncallback=?被替換後,會把方法名稱傳給服務器。咱們在服務器端要作什 麼工做呢?服務器要接受參數jsoncallback,而後把jsoncallback的值做爲JSON數據方法名稱返回,好比服務器是JSP,咱們會這 樣作:web
...ajax
String jsoncallback=request.getParameter("jsoncallback");json
...api
out.print(jsoncallback+"({\"account\":\"XX\",\"passed\":\"true\",\"error\":\"null\"})");
Jquery取得的數據可能以下:
JQUET0988788({"account":"XX","passed":"true","error":"null"})
總結,用JSONP要作兩件事:
1/請求地址加參數:jsoncallback=?
2/服務器段把jsoncallback的值做爲方法名傳回來,如JQUET098788(...)
jQuery從1.2開始就支持XMLHttp跨域請求了,具體怎麼操做?
jQuery中跨域訪問的核心原理:JS文件注入,由於由於script標籤的src屬性是能夠跨域的,利用script標籤的src屬性直接返回非本域名下的數據,具體採用的方式稱爲:jsonp。
代碼:
test.html,例如位於 www.qq.com
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>jQuery-跨域請求</title>
<script type="text/javascript" src="/js/jquery.js"></script>
</head>
<script type="text/javascript">
jQuery(document).ready(function(){
$.ajax({
type : "GET",
url : "http://www.b.com/server.php&action=getmsg&callback=?",
dataType : "jsonp",
jsonp: 'callback',
success : function(json){
$('#msg_box').html(json.msg);
return true;
}
});
});
</script>
<body>
<div id="msg_box"></div>
</body>
</html>
server.php,例如位於www.baidu.com
<?php
$action = $_GET['action'];
$callback = $_GET[callback ];
if ($action)
{
echo "{$callback}({"msg":"this is a jquery jsonp test message!"})";
exit();
}
else
{
echo "{$callback}({"msg":"error action!"})";
exit();
}
?>
今天上午,路路同窗問了一個JQuery跨域讀取json數據的問題。JQuery用得不多,還真沒實際試過。因而上網找個找,看到了JQ的$.getJSON() 方法。先介紹下概念性的東西,網上找的,簡單看看就好了。
1.JSONP(JSON with Padding-填充json數據也就是經常使用的json跨域方式):利用script標籤,經過特定的src地址的調用,來執行一個客戶端的js函數,在 服務器端生成相對的數據(json格式)並以參數的形式傳遞給這個客戶端的js函數並執行這個函數,前提是須要服務器端的數據輸出支持。
2.爲何使用JSONP:因爲 JSON 只是一種含有簡單括號結構的純文本,所以許多通道均可以交換 JSON 消息。由於同源策略的限制,咱們不能在與外部服務器進行通訊的時候使用 XMLHttpRequest。而JSONP是一種能夠繞過同源策略的方法,即經過使用 JSON 與 <script> 標記相結合的方法,從服務端直接返回可執行的JavaScript函數調用或者JavaScript對象。
3.誰在使用JSONP:dojo、JQuery、Youtube GData API 、Google Social Graph API 、Digg API 、GeoNames webservice、豆瓣API、Del.icio.us JSON API等。
------------------------------------------------------------------------------------------------
和 AJAX 同樣,JSONP 實際上也是早已存在,只是說法相對比較新穎(貌似也出來好久了)。自 1.2 版本起,JQuery加入了對 JSONP 的支持(http://docs.jquery.com/Ajax/jQuery.getJSON#urldatacallback)。咱們能夠很容易的利用 $.getJSON() 方法(或者其它基於 $.ajax() 的方法),來跨域加載 JSON 數據。我參考官網,寫了個JQ測試的例子:
a.html
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<script type="text/javascript">
function do_jsonp() {
$.getJSON("http://active.zol.com.cn/guofeng/profile2.php?callback=?",
function(data) {
$('#result').val('My name is: ' + data.nick);
});
}
</script>
<a href="javascript :do_jsonp();">Click me</a><br />
<textarea id="result" cols="50" rows="3"></textarea>
</body>
</html>
profile2.php
<?php
$callback = isset($_GET['callback']) ? $_GET['callback'] : '';
$json = '';
//php數組
$arr = array(
'name' => 'lava',
'nick' => '比目魚',
'contact' => array(
'MSN' => 'lavaguo#msn.com',
'email' => 'guo.feng#zol.com.cn',
'website' => 'http://www.zol.com.cn',
)
);
$arr = gb2312ToUtf8($arr);//中文須要轉UTF-8
$json = json_encode($arr);//轉成json數組
if (!empty($callback)) {
$json = $callback . '(' . $json . ')';//注意這裏的格式,調試時這裏費了點時間
}
echo $json;
function gb2312ToUtf8(&$input)
{
if (!is_array($input)) {
$input = iconv('GB2312', 'UTF-8', $input);
} else {
foreach ($input as $k=>$v) {
gb2312ToUtf8(&$input["$k"]);
}
}
return $input;
}
?>
你可能注意到上面的例子中,url 被寫成了http://active.zol.com.cn/guofeng/profile2.php?callback=?,須要說明的是,這個問號會被 jQuery 自動替換爲回調函數的函數名(若是是一個匿名函數,JQuery 會自動生成一個帶時間戳的函數名)。
總結下JSONP原理:
首先在客戶端註冊一個callback, 而後把callback的名字傳給服務器。
此時,服務器先生成 json 數據。
而後以 javascript 語法的方式,生成一個function , function 名字就是傳遞上來的參數 jsonp.
最後將 json 數據直接以入參的方式,放置到 function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端。
客戶端瀏覽器,解析script標籤,並執行返回的 javascript 文檔,此時數據做爲參數,傳入到了客戶端預先定義好的 callback 函數裏.(動態執行回調函數)