簡談JSONP

1. 同源政策(Same-origin Policy)

瀏覽器出於安全方面的考慮,只容許與同源下的接口交互。javascript

所謂"同源"指的是"三個相同"。php

  • 協議相同:如都是http 或者 https
  • 域名相同:www.example.com/dir 和 www.example.com/dir2/
  • 端口相同:如都是80端口

目前,若是非同源,共有三種行爲受到限制。html

  1. Cookie、LocalStorage 和 IndexDB 沒法讀取。
  2. DOM 沒法得到。
  3. AJAX 請求不能發送。

好比: 用戶打開了 頁面:baidu.com/yyy, 當前頁面下的 js 向 baidu.com/xxx的接口發 ajax 請求,瀏覽器是容許的。但假如向:google.com/xxx發ajax請求則會被瀏覽器阻止掉,由於存在跨域調用。前端

2. JSONP(JSON with padding)

(1)產生的緣由:

  1. Ajax直接請求普通文件存在跨域無權限訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一概不許;
  2. 不過聰明的開發人員們發現,Web頁面上調用 JS 文件時則不受是否跨域的影響(不只如此,還發現凡是擁有 "src" 這個屬性的標籤都擁有跨域的能力,好比<script><img><iframe>);
  3. 因而,當前階段若是想經過純web端跨域訪問數據,就是在遠程服務器上設法把數據裝進 JS 格式的文件裏,供客戶端調用和進一步處理;
  4. 恰巧有一種叫作 JSON 的純字符數據格式能夠簡潔的描述複雜數據,更妙的是 JSON 還被 JS 原生支持
  5. 因此,web客戶端經過與調用腳本如出一轍的方式,來調用跨域服務器上動態生成的JS格式文件(通常以JSON爲後綴),顯而易見,服務器之因此要動態生成JSON文件,目的就在於把客戶端須要的數據裝入進去。
  6. 爲了便於客戶端使用數據,逐漸造成了一種非正式傳輸協議,人們把它稱做JSONP,該協議的一個要點就是容許用戶傳遞一個 callback 參數給服務端,而後服務端返回數據時會將這個 callback 參數做爲函數名來包裹住JSON數據,這樣客戶端就能夠隨意定製本身的函數來自動處理返回數據了。

(2)基本原理

JSONP是服務器與客戶端跨源通訊的經常使用方法。java

它的基本思想是: 網頁經過添加一個 <script> 元素,向服務器請求JSON數據,而且該請求的查詢字符串有一個callback 參數,用來指定回調函數的名字,這種作法不受同源政策限制; 服務器收到請求後,將數據放在一個指定名字的回調函數裏傳回來。jquery

舉個栗子程序員

請求方:frank.com 的前端程序員(瀏覽器)web

響應方:jack.com 的後端程序員(服務器)ajax

  1. 請求方建立 <script>src 指向響應方,同時傳一個查詢參數 ?callbackName=yyy
<script src="http://api.jirengu.com/weather.php?callbackName=showData"></script>
複製代碼
  1. 響應方根據查詢參數 callbackName,構造形如json

    ⅰ. yyy.call(undefined, '你要的數據')

    ⅱ. yyy('你要的數據') 這樣的響應

以前後端返回數據: {"city": "hangzhou", "weather": "晴天"}
如今後端返回數據: showData({"city": "hangzhou", "weather": "晴天"})
複製代碼
  1. 瀏覽器接收到響應,就會執行 yyy.call(undefined, '你要的數據') 那麼請求方就知道了他要的數據

這就是 JSONP。

(3)jQuery 用法

用jQuery實現JSONP調用:

$.ajax({
   url: "http://jack.com:8002/pay",
   dataType: "jsonp",
   success: function( response ) {
     if(response === 'success'){
       amount.innerText = amount.innerText - 1
     }
   }
 })
複製代碼

提問: JSONP 爲何不支持 POST?

答:

  1. 由於 JSONP 是經過動態建立 script標籤實現的
  2. 建立 <script> 只能發送 get 請求

參考連接

相關文章
相關標籤/搜索