咱們將從這幾個方面來分析jsonp跨域訪問javascript
咱們先明白一個概念:同源策略
同源策略是一種瀏覽器的安全策略,一個腳本不能去執行另外一個和他不一樣源的腳本內容。所謂同源指的是域名,協議,端口三個都要相同。因此當咱們經過js獲取第三方的數據時(好比經過第三方API獲取json數據),,瀏覽器是不容許咱們直接這樣作的。因此咱們得使用一種技巧去訪問不一樣域,而後得到該域的數據。這個就是跨域訪問。html
JSON: JavaScript Object Notation(JavaScript 對象表示法)經過名字咱們就大概能夠知道是個啥了,json是一種輕量級的數據交換格式,而這個格式又是遵循的js的對象語法。因此我的認爲json能夠直接看作是js的一個子集。java
jsonp:json with padding 咱們來翻譯一下就是:用來填充的json數據。咦?爲何要這麼叫呢。後面當咱們講到jsonp的原理的時候,你就會知道這樣取名字的緣由了(題外話:取名字真的是個技術活啊。每次遇到函數,變量比較多,如何取個好名字真的很重要)說人話就是:jsonp就是一種訪問數據的非官方傳輸協議。node
經過前面咱們能夠知道因爲同源策略,咱們沒法經過ajax直接去訪問另外一個域名下的文件。那這時咱們怎麼辦,別急,直接不行,咱們間接還不行嗎。咱們仔細想一想咱們的script標籤,它是能夠獲取任何地方的文件的啊。咱們能夠經過它來幫咱們獲取咱們想要的東西。具體如何操做呢,咱們來看例子吧.ajax
首先咱們幻想一下咱們得到了數據以後咱們要幹什麼,咱們把獲取的數據顯示在頁面上吧。
頁面的htmljson
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>測試文件</title> </head> <body> <div> <h1>顯示跨域訪問得到的數據</h1> <div id="show"> </div> </div> </body> </html>
咱們再在頁面中直接添加js函數來處理數據吧跨域
function show(data)//data參數就是咱們從另外一個域獲取到的數據 { var node = document.getElementById('show'); p.innerHTML=p.innerHTML="這就是獲取到的數據 "+data; }
咱們是直接把獲取的數據顯示出來瀏覽器
而後咱們如今去獲取數據,咱們再添加一個節點,裏面的src就是咱們要訪問的第三方的url,只是在url後面咱們額外添加一個callback參數。安全
這是整個的代碼服務器
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>測試文件</title> </head> <body> <div> <h1>顯示跨域訪問得到的數據</h1> <div id="showdata"> </div> </div> <script type="text/javascript"> function show(data)//data參數就是咱們從另外一個域獲取到的數據 { var node = document.getElementById('showdata'); p.innerHTML=p.innerHTML="這就是獲取到的數據 "+data; } </script> <script type="text/javascript" src="url?callback=show"></script> </body> </html>
你們須要注意的是src="url?callback=show",咱們把以前定義的show函數做爲callback參數傳遞給服務器端,這個函數就是一個回調函數,具體過程是這樣:
一個前提是咱們使用jsonp是須要服務器端來配合的,咱們經過url訪問到服務器的地址,而且傳遞了一個callback參數給服務器端,而後服務器端可以接收這個參數,而後將數據以json格式做爲show函數的參數傳遞給它,也就是用json數據來填充這個show函數(如今明白叫jsonp的緣由了吧),而後調用這個函數,最後由於這個函數被執行,咱們的html中的div中就會顯示出獲取到的數據。
不過這樣可能會顯得死板,固定了何時調用。咱們能夠動態生成一個script節點,這樣咱們就能夠在須要數據的時候動態調用了,這樣就會更合理。我仍是上一下完整代碼吧
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>測試文件</title> </head> <body> <div> <h1>顯示跨域訪問得到的數據</h1> <div id="showdata"> </div> </div> <script type="text/javascript"> //data參數就是咱們從另外一個域獲取到的數據 function show(data) { var node = document.getElementById('showdata'); p.innerHTML=p.innerHTML="這就是獲取到的數據 "+data; } function invokeRemoteData() { var node=document.createElement("script"); //remoteUrl就是第三方服務器的地址 var url=remoteUrl?callback=show ; node.setAttribute("src",url); var head=document.getElementsByTagName("head")[0]; //將建立的script節點添加到head的最後,調用開始 head.appendChild(node); } </script> </body> </html>
當咱們須要獲取跨域數據時,直接調用invokeRemoteData函數,html頁面中就會顯示出獲取到的數據。
ps: