jsonp突破同源策略,實現跨域訪問請求

   跨域訪問問題,相信你們都有遇到過。這是一個很棘手的問題。不過道高一尺,魔高一丈,對於這類問題,總有解決問題的方案。最近我又接觸到了這個問題,解決的途徑是ajax+jsonp。javascript

 

       說到這個問題,不得不說一下「同源策略(Same-Origin Policy)」,它是由Netscape提出的一個著名的安全策略。如今全部支持JavaScript 的瀏覽器都會使用這個策略。所謂同源,就是必須協議、域名、端口都一致的,才叫作同源。例如:http://www.12306.cn和https://www.12306.cn,因爲協議不一致,就不是同源。http://127.0.0.1:8080/test1和http://localhost:8080/test1 也不屬於同源,由於域名不一致。端口不一樣固然也不叫同源了。java

 

       若是非同源,那麼在請求數據時,瀏覽器會在控制檯中報一個異常,提示拒絕訪問。這是一個令web開發人員很是手疼的問題。好比,我如今打開百度網頁,而後在控制檯中請求CSDN的網頁,那麼就會報如圖所示的異常:jquery

       在上圖中,你們可能會看到這個詞兒——「Access-Control-Allow-Origin」,它是W3C標準中爲了解決同源策略引發的跨域問題而提出的一種技術——「跨域資源共享(CORS,Cross-Origin Resource Sharing)」。只要你在服務端設定這個Access-Control-Allow-Origin的header就能夠容許跨域訪問了。有興趣的話,本身查一下,很簡單。不過它有安全隱患,主要是由於支持通配符*。每一個網站均可以隨意請求,那就太不安全了。如:web

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. response.setHeader("Access-Control-Allow-Origin", "*");  

 

 

       Query中$.ajax的get方法,是支持跨域訪問的,不過dataType要設定爲「jsonp」。Jsonp(JSON with Padding)是 json 的一種「使用模式」,可讓網頁從別的網域獲取資料。jsonp是採用的js的回調機制來實現的。使用方式也很簡單,代碼以下:ajax

 

[javascript]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1.    
  2. $.ajax({   
  3.   url: 'http://localhost:8080/test2/searchJSONResult.action',  
  4.   type: "GET",   
  5.   dataType: 'jsonp',   
  6.   data: {name:」ZhangHuihua」}, timeout: 5000,   
  7.   success: function (json) {  
  8.     //客戶端jquery預先定義好的callback函數,成功獲取跨域服務器上的json數據後,會動態執行這個callback函數   
  9.     alert(json);   
  10.   },   
  11.   error: function (){  
  12.     alert("請求失敗!");   
  13.    }  
  14. });  
  15.   
  16. //簡單方式以下:  
  17. $.getJSON("http://localhost:8080/test2/searchJSONResult.action?name1=ZhangHuihua&callback=?",  
  18. function(json){ // 執行代碼  
  19. });  


       在服務器端,從新拼接json數據:json

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. /** 獲取請求的各個參數(用戶名等) **/  
  2. Map map = request.getParameterMap();  
  3. /** 獲取jsonp的回調函數名 **/  
  4. String callback = request.getParameter("callback");  
  5. /** 調用業務邏輯,並將結果轉化爲json格式 **/  
  6. String msg = convert2Json(services.login(map))  
  7. /** 從新拼接格式,並輸出  **/  
  8. out.println(callback + "('" + msg + "')");  


       這樣就能夠在瀏覽器獲取到異源服務端返回的json數據了。這裏返回的跟json格式不同,它的格式是回調函數名+(json數組)。其中小括號不能夠省略。不然請求是發送成功了,可是卻獲取不到數據,由於返回的數據格式出錯了。效果圖以下:跨域

 

相關文章
相關標籤/搜索