大多數情況下,無論是框架還是自己實現都是通過Ajax的方式來向後端請求數據的,而Ajax之間是通過傳輸json格式的文件來進行數據的傳輸的,大家對Ajax也很熟悉了,那麼爲什麼我又要使用jsonp呢?這就要從什麼是jsonp,什麼是json來說一說了。
json是一種格式,而jsonp是一種調用方式,那麼在大家都使用Ajax的情況下爲什麼我不用呢?因爲Ajax作爲腳本出於安全的考慮,是不允許訪問非同源的內容的。那麼如果我的前端活動頁面和後端的服務器不在一個域名下該如何請求數據呢?這個時候就需要jsonp的方式來解決跨域的問題了。
那麼爲什麼jsonp可以跨域呢?其中的原理又是什麼呢?我們下面就來介紹一下jsonp跨域的原理。
因爲同源策略的的原因,對於一個瀏覽器的頁面只有來自一個源的腳本纔可以被執行,這樣的目的是爲了安全性,可是卻阻止了數據的請求,所以我們就要從繞開同源策略來入手,什麼情況下允許跨域請求呢?那就是靜態資源!靜態資源是不受域策略限制的,可以加載任意域的腳本、樣式、圖片等靜態資源,JSOP就是利用這種原理來實現跨域獲取數據的。
我們將需要的json數據放在js文件中進行傳輸,這樣就可以將需要的數據通過靜態文件的形式傳過來了,那麼我們就來講講具體是如何實現的呢?
由於是靜態文件,所以我們在請求的時候首先需要建立一個靜態資源的DOM元素,例如這樣的標籤:
<script src="http://cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script>
那麼我們就來一步步的構建這個DOM標籤吧,首先通過document.createElement(‘script’);來建立一個script標籤,然後設置它的src屬性指向需要請求的URL地址,然後將這個元素添加在body中,最後出於安全我們要將剛剛新建的標籤在完成請求後刪除掉。
在這裏我把我寫的一個封裝好的函數貼出來,很簡單的一個函數就說明了一切~
/* * Created by jonnyf on 15-9-15. * 這個函數是通過JSONP的方式請求後端接口 * 需要傳入三個參數, * url爲請求的接口地址,類型爲字符串 * parameter爲請求的參數對象,類型爲對象 * callback爲完成請求後的回調函數名稱, 類型爲字符串 */ function getJSONP(url, parameter, callback) { var Script = document.createElement('script'), _parameter = parameter, _url = url, _callback = callback, code = ''; for (var i in _parameter) { code += i + '=' + _parameter[i] + '&' } Script.src = _url + '?' + code + 'callback=' + _callback; document.body.appendChild(Script); Script.onload = function(){ // 請求成功後移除標籤 Script.remove(); } Script.onerror = function() { // 失敗的時候也要移除標籤 alert('請求錯誤, 請重試'); Script.remove(); }; }