引用:http://www.cnblogs.com/dengzy/p/5388357.htmljavascript
說到AJAX就會不可避免的面臨兩個問題,第一個是AJAX以何種格式來交換數據?第二個是跨域的需求如何解決?數據能夠用自定義字符串或者用XML來描述,跨域能夠經過服務器端代理來解決。最被推崇或者說首選的方案仍是用JSON來傳數據,靠JSONP來跨域。JSON是一種數據交換格式,而JSONP是一種依靠開發人員的聰明才智創造出的一種非官方跨域數據交互協議。php
JSON的格式:html
JSON可以以很是簡單的方式來描述數據結構,XML能作的它都能作。java
1、JSON只有兩種數據類型描述符,大括號{}和方括號[],其他英文冒號:是映射符,英文逗號,是分隔符,英文雙引號""是定義符。jquery
2、大括號{}用來描述一組「不一樣類型的無序鍵值對集合」(每一個鍵值對能夠理解爲OOP的屬性描述),方括號[]用來描述一組「相同類型的有序數據集合」(可對應OOP的數組)。web
3、上述兩種集合中如有多個子項,則經過英文逗號,進行分隔。ajax
4、鍵值對以英文冒號:進行分隔,而且建議鍵名都加上英文雙引號」",以便於不一樣語言的解析。json
5、JSON內部經常使用數據類型無非就是字符串、數字、布爾、日期、null 這麼幾個,字符串必須用雙引號引發來,其他的都不用,日期類型比較特殊,這裏就不展開講述了,只是建議若是客戶端沒有按日期排序功能需求的話,那麼把日期時間直接做爲字符串傳遞就好,能夠省去不少麻煩。api
JSON實例:跨域
var person = { // 描述一我的
"Name": "Bob",
"Age": 32,
"Company": "IBM",
"Engineer": true
}
var personAge = person.Age; // 獲取這我的的信息
var 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
}
]
var johnsCompany = members[1].Company; // 讀取其中John的公司名稱
var conference = { // 描述一次會議
"Conference": "Future Marketing",
"Date": "2012-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
}
]
}
var henryIsAnEngineer = conference.Members[2].Engineer; // 讀取參會者Henry是否工程師
JSONP是怎麼產生的
1、一個衆所周知的問題,Ajax直接請求普通文件存在跨域無權限訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一概不許;
2、不過咱們又發現,Web頁面上調用js文件時則不受是否跨域的影響(不只如此,咱們還發現凡是擁有」src」這個屬性的標籤都擁有跨域的能力,好比<script>、<img>、<iframe>);
3、因而能夠判斷,當前階段若是想經過純web端(ActiveX控件、服務端代理、屬於將來的HTML5之Websocket等方式不算)跨域訪問數據就只有一種可能,那就是在遠程服務器上設法把數據裝進js格式的文件裏,供客戶端調用和進一步處理;
4、恰巧咱們已經知道有一種叫作JSON的純字符數據格式能夠簡潔的描述複雜數據,更妙的是JSON還被js原生支持,因此在客戶端幾乎能夠爲所欲爲的處理這種格式的數據;
5、這樣子解決方案就呼之欲出了,web客戶端經過與調用腳本如出一轍的方式,來調用跨域服務器上動態生成的js格式文件(通常以JSON爲後綴),顯而易見,服務器之因此要動態生成JSON文件,目的就在於把客戶端須要的數據裝入進去。
6、客戶端在對JSON文件調用成功以後,也就得到了本身所需的數據,剩下的就是按照本身需求進行處理和展示了,這種獲取遠程數據的方式看起來很是像AJAX,但其實並不同。
7、爲了便於客戶端使用數據,逐漸造成了一種非正式傳輸協議,人們把它稱做JSONP,該協議的一個要點就是容許用戶傳遞一個callback參數給服務端,而後服務端返回數據時會將這個callback參數做爲函數名來包裹住JSON數據,這樣客戶端就能夠隨意定製本身的函數來自動處理返回數據了。
JSONP的客戶端具體實現:
jQuery也好,ExtJs也罷,又或者是其餘支持jsonp的框架
跨域js文件中的代碼(固然指符合web腳本安全策略的),web頁面也是能夠無條件執行的。
服務端返回http://flightQuery.com/jsonp/flightResult.aspx
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});
jsonp.htm
<!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>
<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>
jQuery如何實現jsonp調用
<!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>
<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、ajax和jsonp這兩種技術在調用方式上「看起來」很像,目的也同樣,都是請求一個url,而後把服務器返回的數據進行處理,所以jquery和ext等框架都把jsonp做爲ajax的一種形式進行了封裝;
2、但ajax和jsonp其實本質上是不一樣的東西。ajax的核心是經過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態添加<script>標籤來調用服務器提供的js腳本。
3、因此說,其實ajax與jsonp的區別不在因而否跨域,ajax經過服務端代理同樣能夠實現跨域,jsonp自己也不排斥同域的數據的獲取。
4、還有就是,jsonp是一種方式或者說非強制性協議,如同ajax同樣,它也不必定非要用json格式來傳遞數據,若是你願意,字符串都行,只不過這樣不利於用jsonp提供公開服務。
jquery在處理jsonp類型的ajax時已把jsonp納入了ajax
angularJS中jsonp的使用
myUrl = "http://localhost:8090/api/testcallback=JSON_CALLBACK";
$http.jsonp(myUrl).success(
function(data){
alert(data);
}
);
1.angularJS中使用$http.jsonp函數
2.指定callback和回調函數名,函數名爲JSON_CALLBACK時,會調用success回調函數,JSON_CALLBACK必須全爲大寫。
3.也能夠指定其它回調函數,但必須是定義在window下的全局函數。
4.url中必須加上callback
5.當callback爲JSON_CALLBACK時,只會調用success,即便window中有JSON_CALLBACK函數,也不會調用該函數。
瀏覽器是存在同源策略這個機制的,在全局層面禁止了頁面加載或執行與自身來源不一樣的域的任何腳本。
JSONP是一種能夠繞過瀏覽器的安全限制,從不一樣的域請求數據的方法。
Jquery中jsonp的使用
myUrl = "http://localhost:8090/api/test";
$.ajax({
type:"GET",
url:myUrl,
dataType:"jsonp",
jsonp:"callback",
jsonpCallback:"jsonpCallback",
success:function(data){
alert(data.msg);
}
});
function jsonpCallback(data){
alert(data);
}
1.jsonp只能使用get請求,解決同源問題,返回javascript代碼,由於請求javascript文件是沒有同源問題的。
2.當請求數據類型爲jsonp時,會將callback=jsonpCallback加在url上,http://localhost:8090/api/testcallback=jsonpCallback
3.前臺javascript中定義jsonpCallback函數,此函數必須定義在window下,也就是全局的函數,不然找不到。
4.後臺獲取請求的callback參數值jsonpCallback,返回字符串"jsonpCallback(result)",result爲返回結果。
5.請求返回的是script tag,首先會調用jsonpCallback函數,不論是否找到該函數,都會調用success函數。
6.若是沒有定義jsonp和jsonpCallback,jsonp默認爲"callback",jsonpCallback會是Jquery自動生成的函數名。