跨域&JSONP

來源:互聯網
上載者:User

標籤:developer   test   因此   協議   with   方式   圖解   fun   函數名   

1. 同源&跨域1.1 什麼是同源?什麼是跨域?
  • 同源:協議頭、網域名稱、連接埠完全一致就叫同源

  • 跨域:協議頭、網域名稱、連接埠有一個不一樣就叫跨域

  • 判斷是否同源,如:http://www.example.com/detail.html 與以下地址對比

對比地址 是否同源 原因
http://api.example.com/detail.html 不同源 網域名稱不同
https://www.example.com/detail.html 不同源 協議不同
http://www.example.com:8080/detail.html 不同源 連接埠不同
http://api.example.com:8080/detail.html 不同源 網域名稱、連接埠不同
https://api.example.com/detail.html 不同源 協議、網域名稱不同
https://www.example.com:8080/detail.html 不同源 連接埠、協議不同
http://www.example.com/other.html 同源 只是目錄不同

 

 

 

 

 

 

 

 

 1.2 跨域的影響
  • 註:根據同源和跨域的意思,跨域就是指不同源
  • 如果要在 localhost/test.html 這個網站上訪問 http://api.douban.com/v2/movie/top250 這個介面,那麼瀏覽器會出現以下錯誤:

  • 原因:瀏覽器本身從安全形度考慮,不支援跨域訪問
2. JSONP2.1 如何突破跨域要求節流2.1.1 使用img標籤(拿不到響應體)

我們知道:img 標籤,有個 href 屬性,這個屬性其實也是向伺服器發送請求,我們看看這種方式是否可以跨越訪問,代碼如下:

<img href="http://api.douban.com/v2/movie/top250" alt="">

此時可以看到能正確收到響應,但拿不到響應體(返回的JSON資料),

2.1.2 使用link標籤(拿不到響應體)

link 標籤,有個 src 屬性,我們以前是用來外聯css樣式,其實它也是相當於發送請求

 <link rel="stylesheet" src="http://api.douban.com/v2/movie/top250"

 看瀏覽器響應報文,可以發現link標籤也可以跨域請求,但是一樣,沒辦法拿到響應體

2.1.3 使用script標籤(曲線拿到響應體)

代碼如下:

1 <script>2     function test(json) {3         console.log(‘我被調用了‘);4         console.log(json);5     }6 </script>7 <script src="http://api.douban.com/v2/movie/top250?callback=test"></script>

結果如

 說明:我們可以看到,我們預先定義了一個函數叫test,再然後在src裡加了一個參數callback=test,可以發現,當請求完成,會自動調用test這個函數,並且把響應體(JSON資料)當做參數傳遞過來

2.2 使用script標籤拿到JSON資料2.2.1 script匯入外部檔案作用
  • 使用script匯入外部檔案時,預設會把檔案內容當JS代碼執行,例:

  • 建立 1.txt 檔案,檔案內容如下:

alert(‘你好‘);
  • 建立 index.html 檔案,核心代碼如下:
<script src="1.txt"></script>

結果:

結論:script匯入檔案會預設把檔案內容當JS代碼執行,跟檔案格式無關

2.2.2 script標籤曲線拿到響應體原理
  • 建立 index.html 頁面,代碼如下
1 <script>2     //聲明一個success函數3     function success(obj){4         console.log(obj);5     }6 </script>7 <!-- script匯入檔案 -->8 <script src="http://www.demo.com/top250.php"></script>
  • 建立 top250.php 頁面,代碼如下
echo "success(‘hello‘)";

結果

說明:請求的top250檔案裡,伺服器最終返回的是 success(‘hello‘); 這個當JS代碼執行時,是調用函數並傳遞參數hello的文法,因此可以看到success函數被調用,並且列印了參數hello

圖解:

★★ 思考:如果在上例中,把success函數的參數換成json對象,會怎樣?

  • 修改 top250.php 代碼,如下:
1     $data = array(‘name‘ => ‘jack‘,‘age‘=>16,‘gender‘=>‘true‘ );2 3     $json = json_encode($data);4 5     echo "success({$json})"; 
  • 再次訪問網頁可以發現,列印的參數就變成了json對象

結論:script標籤拿到JSON資料的原理就是在伺服器端寫呼叫瀏覽器端函數的方法 ,然後把JSON資料當參數傳遞過去

★★ 思考:現在服務端代碼這麼寫,如果要解決跨域問題,是不是每個瀏覽器端都要準備一個名叫success的函數?能讓瀏覽器端自己指定嗎?怎麼指定?

  • 請求資料時加參數,修改 index.html
1 <script>2     //聲明函數3     function myFunc(obj){4         console.log(obj);5     }6 </script>7 8 <!-- 請求資料,並加入callback參數,值為myFunc -->9 <script src="http://www.demo.com/top250.php?callback=myFunc"></script>
  • 此時,除了請求 top250.php 外,還傳遞了個 callback 的參數過去,修改 top250.php,拿到這個參數
 1 <?php 2  3     //拿到傳遞過來的參數,即函數名 4     $funcName = $_GET[‘callback‘]; 5  6     //準備資料 7     $data = array(‘name‘ => ‘jack‘,‘age‘=>16,‘gender‘=>true ); 8  9     //轉化為JSON10     $json = json_encode($data);11 12     //傳過來的是什麼函數名,就調用什麼函數13     echo "$funcName($json)"; 14 ?>

結果:此時就完成了指定函數名讓伺服器調用傳參的效果了。

這就是之前跨域拿資料的原理,即伺服器端呼叫瀏覽器端的函數,把參數傳遞過來即可

2.3 JSONP概念總結
  • JSONP:

    • JSON with Padding 是一種藉助於script標籤發送跨域請求的技巧方案。

  • 它不是一套新技術,只是聰明的程式員想出的一套方案

  • 能不能用這套方案,要看伺服器端代碼怎麼寫,伺服器端如果寫了調用函數的代碼,那麼就能支援JSONP方案

  • 以後伺服器的介面會有介面文檔進行說明是否支援JSONP

  • 建議:不要隨意使用別人的介面,特別是別人寫的支援JSONP的介面

    例:https://developers.douban.com/wiki/?title=api_v2

3. CORS
  • Cross Origin Resource Share,跨域資源共用

  • 直接從伺服器端解決ajax無法跨域訪問的問題(可以不要用jsonp了)

// 允許遠端訪問header(‘Access-Control-Allow-Origin: *‘);

這種方案無需用戶端作出任何變化(用戶端不用改代碼),只是在服務端添加一個 Access-Control-Allow-Origin 的回應標頭,表示這個資源是否允許指定域請求(*代表任何網站都可以訪問)。

跨域&JSONP

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.