我的理解,用post就有跨域檢查了。jsonp實際是在客戶端動態(tài)添加了個script標(biāo)簽,然后將url指向要請求的地址,script是沒有同源策略的。用這種辦法自然只能是get了。
jsonp的本質(zhì)是:動態(tài)創(chuàng)建script標(biāo)簽,然后通過他的src屬性發(fā)送跨域請求,不同意然后服務(wù)器相應(yīng)的數(shù)據(jù)格式為【函數(shù)調(diào)用foo(實參)】,所以在發(fā)送請求之前必須聲明一個函數(shù),并且函數(shù)的名字與參數(shù)中傳遞的名字要一致。
原理就是從服務(wù)端加載一段腳本(用script標(biāo)簽),然后把數(shù)據(jù)放到一個函數(shù)參數(shù)里面,再然后瀏覽器里定義的那個函數(shù)就能拿到那個數(shù)據(jù)了~
所以為啥不能發(fā)post 因為標(biāo)簽里只能發(fā)get
jsonp與ajax
雖然, jsonp 的實現(xiàn)跟 ajax 沒有半毛錢關(guān)系,jsonp是通過 script的src實現(xiàn)的,但是最終目的都是向服務(wù)器請求數(shù)據(jù)然后回調(diào),而且為了方便,所以jquery把 jsonp 也封裝在了 $.ajax 方法中,調(diào)用方式與 ajax 調(diào)用方式略有區(qū)別。
這里針對ajax與jsonp的異同再做一些補充說明:
1、ajax和jsonp這兩種技術(shù)在調(diào)用方式上”看起來”很像,目的也一樣,都是請求一個url,然后把服務(wù)器返回的數(shù)據(jù)進行處理,因此jquery和ext等框架都把jsonp作為ajax的一種形式進行了封裝。
2、但ajax和jsonp其實本質(zhì)上是不同的東西。ajax的核心是通過XmlHttpRequest獲取非本頁內(nèi)容,而jsonp的核心則是動態(tài)添加;
JSONP的客戶端具體實現(xiàn):
不管jQuery也好,extjs也罷,又或者是其他支持jsonp的框架,他們幕后所做的工作都是一樣的,下面我來循序漸進的說明一下jsonp在客戶端的實現(xiàn):
1、我們知道,哪怕跨域js文件中的代碼(當(dāng)然指符合web腳本安全策略的),web頁面也是可以無條件執(zhí)行的。
遠(yuǎn)程服務(wù)器remoteserver.com根目錄下有個remote.js文件代碼如下:

本地服務(wù)器localserver.com下有個jsonp.html頁面代碼如下:

2、現(xiàn)在我們在jsonp.html頁面定義一個函數(shù),然后在遠(yuǎn)程remote.js中傳入數(shù)據(jù)進行調(diào)用。
jsonp.html頁面代碼如下:

remote.js文件代碼如下:

運行之后查看結(jié)果,頁面成功彈出提示窗口,顯示本地函數(shù)被跨域的遠(yuǎn)程js調(diào)用成功,并且還接收到了遠(yuǎn)程js帶來的數(shù)據(jù)。
很欣喜,跨域遠(yuǎn)程獲取數(shù)據(jù)的目的基本實現(xiàn)了,但是又一個問題出現(xiàn)了,我怎么讓遠(yuǎn)程js知道它應(yīng)該調(diào)用的本地函數(shù)叫什么名字呢?畢竟是jsonp的服務(wù)者都要面對很多服務(wù)對象,而這些服務(wù)對象各自的本地函數(shù)都不相同???我們接著往下看。
3、聰明的開發(fā)者很容易想到,只要服務(wù)端提供的js腳本是動態(tài)生成的就行了唄,這樣調(diào)用者可以傳一個參數(shù)過去告訴服務(wù)端 “我想要一段調(diào)用XXX函數(shù)的js代碼,請你返回給我”,于是服務(wù)器就可以按照客戶端的需求來生成js腳本并響應(yīng)了。
看jsonp.html頁面的代碼:

這次的代碼變化比較大,不再直接把遠(yuǎn)程js文件寫死,而是編碼實現(xiàn)動態(tài)查詢,而這也正是jsonp客戶端實現(xiàn)的核心部分,本例中的重點也就在于如何完成jsonp調(diào)用的全過程。
我們看到調(diào)用的url中傳遞了一個code參數(shù),告訴服務(wù)器我要查的是CA1998次航班的信息,而callback參數(shù)則告訴服務(wù)器,我的本地回調(diào)函數(shù)叫做flightHandler,所以請把查詢結(jié)果傳入這個函數(shù)中進行調(diào)用。
OK,服務(wù)器很聰明,這個叫做flightResult.aspx的頁面生成了一段這樣的代碼提供給jsonp.html
(服務(wù)端的實現(xiàn)這里就不演示了,與你選用的語言無關(guān),說到底就是拼接字符串):

4、到這里為止的話,相信你已經(jīng)能夠理解jsonp的客戶端實現(xiàn)原理了吧?剩下的就是如何把代碼封裝一下,以便于與用戶界面交互,從而實現(xiàn)多次和重復(fù)調(diào)用
jQuery如何實現(xiàn)jsonp調(diào)用?
<!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回調(diào)函數(shù)名的參數(shù)名(一般默認(rèn)為:callback)
?????????????jsonpCallback:"flightHandler",//自定義的jsonp回調(diào)函數(shù)名稱,默認(rèn)為jQuery自動生成的隨機函數(shù)名,也可以寫"?",jQuery會自動為你處理數(shù)據(jù)
?????????????success:?function(json){
?????????????????alert('您查詢到航班信息:票價:?'?+?json.price?+?'?元,余票:?'?+?json.tickets?+?'?張。');
?????????????},
?????????????error:?function(){
?????????????????alert('fail');
?????????????}
?????????});
?????});
?????</script>
?????</head>
??<body>
??</body>
</html>
是不是有點奇怪?為什么我這次沒有寫flightHandler這個函數(shù)呢?而且竟然也運行成功了!
這就是jQuery的功勞了,jquery在處理jsonp類型的ajax時(,雖然jquery也把jsonp歸入了ajax,但其實它們真的不是一回事兒),自動幫你生成回調(diào)函數(shù)并把數(shù)據(jù)取出來供success屬性方法來調(diào)用。