Jsonp跨域訪問

很早以前看過好幾篇跨域訪問的文章,而後作項目的時候基本沒有遇到跨域訪問的問題。不過該來的仍是會來,前些天終於讓我遇到了。因而重溫了一下原理這些,再進行實戰。因而如今也敢經過實戰後的一些理解來和你們分享了。

咱們今天主要來分享的就是jsonp的跨域訪問。

咱們將從這幾個方面來分析jsonp跨域訪問javascript

  • 跨域訪問是什麼
  • json是什麼
  • jsonp是什麼
  • 如何進行jsonp跨域訪問

1.跨域訪問是什麼

咱們先明白一個概念:同源策略

同源策略是一種瀏覽器的安全策略,一個腳本不能去執行另外一個和他不一樣源的腳本內容。所謂同源指的是域名,協議,端口三個都要相同。因此當咱們經過js獲取第三方的數據時(好比經過第三方API獲取json數據),,瀏覽器是不容許咱們直接這樣作的。因此咱們得使用一種技巧去訪問不一樣域,而後得到該域的數據。這個就是跨域訪問。html

2.json是什麼

JSON: JavaScript Object Notation(JavaScript 對象表示法)經過名字咱們就大概能夠知道是個啥了,json是一種輕量級的數據交換格式,而這個格式又是遵循的js的對象語法。因此我的認爲json能夠直接看作是js的一個子集。java

3.jsonp是什麼

jsonp:json with padding 咱們來翻譯一下就是:用來填充的json數據。咦?爲何要這麼叫呢。後面當咱們講到jsonp的原理的時候,你就會知道這樣取名字的緣由了(題外話:取名字真的是個技術活啊。每次遇到函數,變量比較多,如何取個好名字真的很重要)說人話就是:jsonp就是一種訪問數據的非官方傳輸協議。node

4.如何進行jsonp跨域訪問

經過前面咱們能夠知道因爲同源策略,咱們沒法經過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頁面中就會顯示出獲取到的數據。

總結一下,完成jsonp跨域訪問所須要作的步驟:

  • 建立一個函數,這個函數是用來處理獲取到的數據
  • 給要訪問的遠程url添加一個callback參數並將以前建立的處理函數做爲callback參數的值
  • 能夠添加一個方法來動態建立一個script標籤以此來動態獲取數據

ps:

  • 此前提到了回調函數,簡單說回調函數就是把該函數當作參數傳遞給另一個函數,而後在須要的時候在這個函數中調用傳入的回調函數。
  • 推薦兩篇jsonp講的很好的博客,廖雪峯ajax隨它去吧-jsonp 這兩位都是大牛,個人這篇只是個人我的理解,你們能夠多看看不一樣的人寫的,而後總結一下
  • 還推薦一個跨域訪問的方法:就是服務器端代理,先請求服務器,而後服務器端幫你請求須要的文件再response給你。
相關文章
相關標籤/搜索