細說jsonp

pythontab發表於2013-07-29

什麼是jsonp

jsonp充其量只能說是一種“方法”。它可以讓頁面從其他域中獲取資料。

首先要知道的是同源策略,在javascript中使用http請求(ajax)是會受到同源策略的限制的。A網站的頁面是不能在javascript中訪問B網站的資源的。但是,對於這種希望A網站訪問B網站的資源的需求怎麼辦呢?(跨域訪問)。jsonp就出現了。

html中雖然說javascript是不能跨域的,但是有許多標籤,比如<img>,<iframe>,<script>這些有src屬性的標籤是不受同源策略的影響的。於是jsonp就把腦筋動到script標籤上了。一般script都是靜態的,但是script能否是動態的呢?

比如我在script的src中的url帶上使用者id,這樣來訪問一個跨域的請求,請求返回這個使用者的個人資訊,我再使用這個個人資訊來渲染我的頁面。這樣不就可以完成了一個跨域請求了。但是呢?script中返回的必須是javascript,所以呢,一般就約定,src中的url除了要帶動態請求所需要的資訊以外,還需要帶一個回撥資訊(一般是一個回撥函式),讓請求返回的資料是一個可執行的javascript的完整語句。

比如:

function handle_data(data) {

  // `data` is now the object representation of the JSON data

}

http://www.aaa.com/service?callback=data:

handle_data({"data_1": "hello world", "data_2": ["the","sun","is","shining"]});

再問個經常問到的問題,jsonp和ajax,json有什麼關係呢?

首先jsonp和ajax完全是兩個概念,可以說jsonp出現的理由就是彌補ajax無法跨域訪問的缺陷而出現的。所以這兩個概念沒啥關係。至於有些框架,比如jquery喜歡把ajax和jsonp放在一起,完全是由於他們的呼叫和使用方式很相像而已。

jsonp返回的資料並不是json,而是javascrip,比如上例中的handle_date中返回的資料一定要是json麼?從來沒人這麼說過。再次吐槽下,特別是前端的這些概念的名詞確實起的很容易讓人迷糊。

jsonp有什麼優點呢?

第一個優點當然是能跨域了。一個訪問不再受限於域名了,這個代表什麼呢?代表我可以提供一個公共的webservice了,這個服務可以給你服務,也可以給他服務,你們不需要一定是在我的域名下的。

其次的優點是將回撥方法的許可權給了呼叫方。這個就相當於將controller層和view層終於分開了。我提供的jsonp服務只提供純服務的資料,至於提供服務以後的頁面渲染和後續view操作都由呼叫者來自己定義就好了。如果有兩個頁面需要渲染同一份資料,你們只需要有不同的渲染邏輯就可以了,邏輯都可以使用同一個jsonp服務。

還有一個優點是它甚至不需要瀏覽器能支援XMLHTTPRequest,就是說所有的瀏覽器都可以使用這個技術。

json有什麼缺點呢

首先的缺點是安全性。萬一假如提供jsonp的服務存在頁面注入漏洞,即它返回的javascript的內容被人控制的。那麼結果是什麼?所有呼叫這個jsonp的網站都會存在漏洞。於是無法把危險控制在一個域名下…所以在使用jsonp的時候必須要保證使用的jsonp服務必須是安全可信的。

其次是錯誤處理,jsonp在呼叫失敗的時候不會返回各種HTTP狀態碼。只有200,沒有404,沒有500等狀態碼讓你來標識是否要重新呼叫。

它只能支援GET,而不能支援POST請求,所以它的引數一定是帶在HTTP頭中的,會受到一些引數的限制,比如長度限制。


相關文章