解決跨域的兩種方案JSONP和CORS

B_Cornelius發表於2017-09-22

講跨域之前,我們先來講同源策略(SOP),同源策略是網景公司提出的一個著名安全策略。所謂同源就是域名、協議、埠相同。例如www.12306.cn中,http就是超文字傳輸協議,12306就是域名,cn就是埠。如果兩個資源需要通訊,那麼他必須滿足SOP。而在前端中我們使用ajax進行資料請求。
如果資源不同域,那麼我們在使用ajax請求資料的時候,就會報錯,表示拒絕訪問。那如何進行跨域處理呢?事實上有三種方法1、JSONP,2、子域代理,3、CORS。由於第二種方法如今已經採用的非常少,所以我們在這兒不做講解

一、JSONP(JSON with Padding)

帶填充的JSON,是一種可以在JS中繞過同源策略,併發起跨域HTTP請求的使用模式,可以啟動JS的跨域HTTP請求
同源策略有一個顯著的例外,HTML指令碼元素是可以規避SOP檢查的。那就意味著我們可以採用動態注入指令碼的方式向其他源發出HTTP請求。JSONP正是利用了這個例外情況進行跨域資料載入的。

1、工作原理

我們先來看一個例子:使用ajax請求一個普通的JSON檔案。假設你使用ajax請求'jsonpjs.com/info.json…

{
    'title': 'jsonp explaintation',
    'author': 'Cornelius'
}複製程式碼

瀏覽器接受到這個json檔案後,就會把他當成字串進行處理,但是這個字串我們需要把它轉換為物件,才能夠被javascript所使用,這裡我們就可以使用json.parse函式來完成。當然由於同源策略的限制,ajax只能夠在同一個域中才能夠使用。但是正如我們前面提到的,script是html指令碼元素它可以規避SOP的檢查所以我們為了請求到json檔案,我們可以使用這種方式

通過script元素請求資源,當檔案載入完成時,瀏覽器會把json響應當作Javascript解析。但是這樣的情況下我們還是無法獲得json資料。
由於該物件沒有被儲存,也沒有賦值給一個變數,或者作為引數傳遞給一個函式,瀏覽器就會忽略它。
那麼該如何獲取JSON輸出呢?
這兒有兩種方法,第一種直接由伺服器把json資料進行儲存。例如有一個外部URL,jsonjs.com//info.js(注意…
var jsonResponse = {
'title': 'jsonp explaintation',
'author': 'Cornelius'
}

當檔案載入完成後,我們就可以通過全域性變數jsonResponse訪問這個JSON物件了。當該變數包含所請求資料時,我們可以使用script.onload來通知程式碼。那麼另外一種通過一個回撥函式代替全域性變數的方式來傳遞JSON物件

jsonHandler({
    'title': 'jsonp explaintation',
    'author': 'Cornelius'
})複製程式碼

使用這種方式的好處在於,我們不需要依靠script元素的onload事件來判斷json是否可用,當info.js被解析時,回撥便會自動執行。這需要載入

相關文章