前端跨域解決辦法之JSONP
阿新 • • 發佈:2019-01-30
由於JavaScript的同源策略限制,在當前JavaScript指令碼中並不能操作來自非同一域下的資源,這就使得跨域問題之於前端工程師就像彈吉他之於民謠歌手——是非常重要的基本功。
跨域問題解決辦法有很多種,比如W3C給出的CORS(Cross-Origin Resource Sharing,跨源資源共享),它的基本思想就是使用自定義的HTTP頭部讓瀏覽器與伺服器進行溝通,從而決定請求或響應是應該成功還是失敗;又比如以本域下的後端伺服器做代理轉發請求,從而獲得資源來供給本域下的JavaScript使用;以上,都不是我想說的重點,重點是我想說一下JSONP。
JavaScript雖然受同源策略影響,但是script標籤載入資源並不會被它限制。JSONP就是利用這一點進行跨域資源請求,在資源載入進來之前定義好一個函式,這個函式接收一個引數(資料),函式裡面利用這個引數做一些事情然後需要的時候通過script標籤載入對應遠端檔案資源,當遠端的檔案資源被載入進來的時候,就會去執行我們前面定義好的函式,並且把資料當作這個函式的引數傳入進去。即,JSON with Padding,載入進來的資源一般是以json形式存在的,而這些資源被當做引數傳遞給回撥函式。
擼程式碼:
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>無標題文件</title> <script> function fn(data) { var oUl1 = document.getElementById('ul1'); var html = ''; for (var i=0; i<data.length; i++) { html += '<li>'+data[i]+'</li>'; } oUl1.innerHTML = html; } window.onload = function() { var oBtn1 = document.getElementById('btn1'); oBtn1.onclick = function() { var oScript = document.createElement('script'); oScript.src = 'getData.php'; document.body.appendChild(oScript); } } </script> </head> <body> <span style="white-space:pre"> </span><input type="button" id="btn1" value="按鈕" /> <span style="white-space:pre"> </span><ul id="ul1"></ul> </body> </html>
以下是被呼叫的php檔案:
可以看到,在php中以函式呼叫的形式輸出,並將引數傳入,這樣即使php檔案不在同一個域下,前端的JavaScript也能請求到,並且利用已經宣告的函式進行呼叫。我們還可以將script的src屬性改為有引數的形式:'getData.php?t=str',這樣可以得到另外的資源。<?php $t = isset($_GET['t']) ? $_GET['t'] : 'num'; $callback = isset($_GET['callback']) ? $_GET['callback'] : 'fn'; $arr1 = array('111111','22222222','33333333','4444444','555555555555555555555'); $arr2 = array('aaaaaaaaaaaa','bbbbbbbb','cccccccccccc','ddddddddd','eeeeeeeeeeee'); if ($t == 'num') { $data = json_encode($arr1); } else { $data = json_encode($arr2); } echo $callback.'('.$data.');';
同樣的道理,我們還可以做一些更復雜豐富的應用。比如利用一些入口網站給出的api介面可以呼叫他們資料庫裡的資源,去完成我們想實現的各種功能,以後有機會再接著聊這個話題。