利用JSONP實現跨域請求

  前言:有時候一忙起來就沒了時間觀念,原來我已經有十多天沒寫博客了。一直想作跨域方面的嘗試,無奈最近準備校招沒時間動動手。今天就先講講JSONP吧,昨晚還在研究QQ空間日誌裏面網絡圖片的問題呢,我發現日誌還提供了HTML模式,咱們能夠利用img標籤的src屬性實現跨域請求,從本身的服務器裏提取動態內容。php

JSONPjquery

  在講實現以前,咱們先來看看何爲JSONP。如下是維基百科的解釋:web

  JSONP or "JSON with padding" is a communication technique used in JavaScript programs running in web browsers to request data from a server in a different domain, something prohibited by typical web browsers because of the same-origin policy. JSONP takes advantage of the fact that browsers do not enforce the same-origin policy on <script> tags. Since it works through <script> tags, JSONP supports only the GET request method. There are significant security implications and risks associated to using JSONP; unless you have no choice, CORS is usually the better choice.ajax

  我粗陋翻譯一下:JSONP又稱JSON with padding,它是用在瀏覽器上運行的JS程序裏的一項交互技術,目的是爲了從不一樣的服務器域名上請求數據。因爲同源政策的限制,部分功能會受到瀏覽器的禁止。JSONP利用的是瀏覽器不會對<script>標籤實施同源政策的狀況。又由於它是經過<script>做用的,因此JSONP只支持GET請求方式。但值得注意的是,使用JSONP會存在安全隱患和危險。CORS(跨域資源共享,Cross-Origin Resource Sharing)是一個更爲經常使用的佳選,除非你沒得選。json

解釋:  跨域

  簡單來講就是,通常狀況下,在本域名的頁面想要獲取其餘域名下的數據是會受到限制的。可是在HTML頁面中的<script>(img,iframe亦可)就突破了這種限制,能夠經過src屬性來訪問其餘域名並得到返回的數據,但這種方法並不安全,只能經過GET方法獲取。瀏覽器

  其實咱們日常稍加留意,就不難發現其實咱們日常在頁面中使用CDN也是這個原理,咱們的頁面一樣能夠訪問其餘服務器上的JS文件。緩存

  如咱們經常使用的百度CDN,咱們一般在<head>裏面加上是<script>標籤就可使用其餘服務器的CDN。安全

  <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js"></script>服務器

  只不過稍有不一樣的是如今變爲向服務器運行文件請求數據,而後再以JavaScript的形式返回。

客戶端實現:

  JSONP是一種非正式傳輸協議,具體傳輸內容以及格式能夠由用戶本身定義。不過我以爲JSONP可能會在ES6中新增也說不定哦,到時候可能會規範傳輸格式。JSONP其中有一個要點就是容許用戶傳遞一個callback參數給服務端,而後服務端輸出的數據做爲callback的參數再一併返回到客戶端頁面,最後根據參數在客戶端頁面執行這個回調函數,最終達到返回數據並處理的目的。

  代碼形式以下:

 1 <head>
 2     <meta charset="UTF-8">
 3     <title>JSONP</title>
 4     <script type="text/javscript">
 5         var cbFn = function(str){
 6             alert(str);
 7         }
 8     </script>
 9     <script src="http://www.sp0.baidu.com?data=value&cb=cbFn"></script>
10 </head>

  首先要預約義一個回調函數,用於處理返回數據;其次請求數據的<script>標籤的src要傳遞請求參數以及回調的函數名字到後臺,這一點要溝通協調好。

  因爲在實際應用中請求地址、請求參數以及次數都是不固定的,因此咱們要把JSONP封裝成一個函數,加強靈活性和複用性。

 1   var s1;
 2   function jsonp(url,data,cb){
 3     data.cb = cb?cb:"callback";
 4     data.t = new Date().getTime();
 5     for (var i in data){
 6         var str = i+"="+data[i];
 7         arr.push(str);
 8    }
 9    var str = url+"?"+arr.join("&");
10    var headEl = document.getElementsByTagName("head")[0];
11    if (s1){
12          headEl.removeChild(s1);
13    }    
14    s1 = document.createElement("script");
15    s1.src = str;
16    headEl.appendChild(s1);
17 }

  代碼解釋:首先給傳遞的數據中插入一個回調函數名和一個新的時間參數值,讓後臺獲取你要回調的函數名以及防止調用緩存。接下來就是判斷以前已是否發送過JSONP請求,若是存在,則刪除重建。

服務端實現:

  假設我在客戶端執行了如下請求

1 jsonp("http://www.chengguanhui.com/test.php",{
2     name:"ray",
3     age:23
4 },"cbFn");
5 
6 cbFn(str){
7     alert(str);
8 }

  那麼HTTP傳遞的URL爲http://www.chengguanhui.com/test.php?name=ray&age=23cb=cbFn&t=242566(某個不定時間值)

  PHP代碼:

1 <?php
2     require_once("common.php");
3     $name = $_GET['name'];
4     $age = $_GET['age'];
5     $cb = $_GET['cb'];
6     $str = $name.$age;
7     echo $cb."(".$str.")";
8 ?>

  客戶端接收到cbFn("ray23")並彈出對應內容。

 JQ實現:

  $.ajax(url,[settings])

 1  $.ajax({
 2              type: "get",
 3              url: "http://www.chengguanhui.com/test.php",
 4              dataType: "jsonp",
 5              data: "name=ray&age=23",
 6              jsonp: "callback",//傳遞給請求處理程序或頁面的,用以得到jsonp回調函數名的參數名(通常默認爲:callback)
 7              jsonpCallback:"handleFn",//自定義的jsonp回調函數名稱,默認爲jQuery自動生成的隨機函數名,也能夠寫"?",jQuery會自動爲你處理數據
 8              success: function(json){
 9                  alert(json.name+json.age);
10              },
11              error: function(){
12                  alert('fail');
13              }
14          });
15      });

 

  $.getJSON(url,data,callback)

 1 $.getJSON("http://www.chengguanhui.com/test.php",//若是請求值固定時,能夠省略data參數而直接寫在url參數裏。  2     {
 3     name:ray,
 4     age:23
 5 },
 6 function(data){
 7   $.each(data.items, function(i,item){
 8      alert(i+item);
 9   });
10 });

  說明:原創文章,轉載全文內容或非翻譯內容時,請註明出處與做者。謝謝。

相關文章
相關標籤/搜索