jsonp為什么不支持post請求及jsonp的實現(xiàn)

我的理解,用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)用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 我的理解,用post就有跨域檢查了。jsonp實際是在客戶端動態(tài)添加了個script標(biāo)簽,然后將url指向要請求的...
    黃威_f537閱讀 680評論 0 0
  • 1、一個眾所周知的問題,Ajax直接請求普通文件存在跨域無權(quán)限訪問的問題,甭管你是靜態(tài)頁面、動態(tài)網(wǎng)頁、web服務(wù)、...
    千尋_GHSA閱讀 197評論 0 0
  • 前言: 說到AJAX就會不可避免的面臨兩個問題,第一個是AJAX以何種格式來交換數(shù)據(jù)?第二個是跨域的需求如何解決?...
    小雨雪smile閱讀 451評論 0 2
  • 本文轉(zhuǎn)自,博客園,昵稱:[隨它去吧],http://www.cnblogs.com/dowinning/archi...
    戰(zhàn)神飄雪閱讀 974評論 0 6
  • 說到AJAX就會不可避免的面臨兩個問題,第一個是AJAX以何種格式來交換數(shù)據(jù)?第二個是跨域的需求如何解決?這兩個問...
    叫我峰兄閱讀 246評論 0 2

友情鏈接更多精彩內(nèi)容