jsonp產生的背景
1.從原網站向目標網站(服務端)發送ajax請的時候,由於瀏覽器的安全策略(這兩個網站只要域名,端口,協議 有一個不同就不允許請求訪問)導致跨域,從而請求無法正常進行。
2.Web頁面上調用js文件時則不受是否跨域的影響(不僅如此,我們還發現凡是擁有"src"這個屬性的標簽都擁有跨域的能力,比如<script>、<img>、<iframe>)。
3.於是可以判斷,當前階段如果想通過純web端跨域訪問數據就只有一種可能,那就是在遠程服務器上設法把數據裝進js格式的文件里,供客戶端調用和進一步處理。
4.從服務器端請求到的js代碼是立即執行的,想要處理請求到的數據,可以把服務器端的數據放在一個方法里面,跟隨數據一起返回,瀏覽器端獲取到js代碼后,立即執行此方法,於此同時瀏覽器端需要先定義這個方法,供服務器返回的js調用,這個方法就是所謂的callBack。
做實驗,了解大概流程
比如服務端(www.abc.com)的根目錄下有個 test.js 文件,代碼如下:
alert('hello')
本地服務器127.0.0.1:3000 下有個demo.html頁面代碼如下:
<!DOCTYPE html> <html> <head> <title></title> </head> <body> <script type="text/javascript" src='http://www.abc.com/test.js'></script> </body> </html>
這時候頁面就會彈出 'hello', 因為alert是瀏覽器自帶的函數。
這時候 把 test.js 的內容改成如下:
testFunction('hello')
再打開demo.html頁面,就會報錯如下:
因為在瀏覽器端沒有找到testFunction方法,這就需要在瀏覽器端要事先定義好要執行的這個testFunction方法。
在瀏覽器加上testFunction方法后,代碼如下:
<!DOCTYPE html> <html> <head> <title></title> </head> <body> <script type="text/javascript"> var testFunction = function(data){ alert('執行testFunction' + data) } </script> <script type="text/javascript" src='http://127.0.0.1:3000/users'></script> </body> </html>
運行demo.html 結果如下:
實驗總結
1.服務端返回一個函數,並且函數包裹着瀏覽器端需要的數據。
2.瀏覽器端定義一個函數,跟服務端返回的函數名一樣,用來處理獲取到的數據。
瀏覽器端具體代碼實現
<!DOCTYPE html> <html> <head> <title></title> </head> <body> <script type="text/javascript"> var testFunction = function(data){ alert('執行testFunction' + data.message) } </script>
<!-- 把瀏覽器定義的方法以參數的形式傳遞給服務端就是 callback=testFunction --> <script type="text/javascript" src='http://127.0.0.1:3000/users?callback=testFunction'></script> </body> </html>
服務端代碼,以node.js為例
const express = require('express'); const app= express(); app.get('/users', (req, res)=>{ // 這一步JSONP必備 var _callback = req.query.callback; // 這個responseData是后台要傳回給前台的數據 var responseData = { status: '1', message: 'hello, 你好'}; if (_callback){ // 這兩步設置發送也是NODE.JS發送JSONP必備 res.type('text/javascript'); res.send(_callback + '(' + JSON.stringify(responseData) + ')'); } else{ res.json(responseData); } }); app.listen(8080, ()=>{ console.log('Server is running at http://localhost:8080') })
完成,jsonp的過程就是這樣了,jquery這類框架的 jsonp 是其實就把這個過程給封裝好了, 由於需要把參數都放在 <script> 的 src里面向服務端請求, 所以jsonp只持之get請求。