標籤:spring mvc ajax jsonp cors 跨域
背景:AJAX向後台(springmvc)發送請求,報錯:封鎖交叉源請求:同源策略不允許讀取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的遠端資源。可以將資源移動到相同的網域名稱上或者啟用 CORS 來解決這個問題。
百度一下,發現是遇到了跨域請求請求問題。搜集資料如下
JSONP解釋
在解釋JSONP之前,我們需要瞭解下”同源策略“這個概念,這對理解跨域有協助。基於安全的原因,瀏覽器是存在同源策略機制的,同源策略阻止從一個源載入的文檔或指令碼擷取或設定另一個源載入額文檔的屬性。有點繞,說的簡單點就是瀏覽器限制指令碼只能和同協議、同網域名稱、同連接埠的指令碼進行互動。
JSONP就是為瞭解決這一問題的,JSONP是英文JSON with Padding的縮寫,是一個非官方的協議。他允許服務端產生script tags返回值用戶端,通過javascript callback的形式來實現網站訪問。JSONP是一種script tag的注入,將server返回的response添加到頁面是實現特定功能。
簡而言之,JSONP本身不是複雜的東西,就是通過scirpt標籤對javascript文檔的動態解析繞過了瀏覽器的同源策略。
JSONP原理及實現
接下來,來實際類比一個跨域請求的解決方案。後端為Spring MVC架構的,前端則通過Ajax進行跨域訪問。
1、首先用戶端需要註冊一個callback(服務端通過該callback(jsonp)可以得到js函數名(jsonpCallback)),然後以JavaScript語
法的方式,產生一個function
2、接下來,將JSON資料直接以入參的方式,放置到function中,這樣就產生了一段js文法文檔,返回給用戶端。
3、最後用戶端瀏覽器動態解析script標籤,並執行返回的JavaScript文法文檔片段,此時資料作為參數傳入到了預先定義好的
回呼函數裡(動態執行回呼函數)。
這種動態解析js文檔和eval函數是類似的。
經過一番努力,解決如下:
SpringMVC端:
@RequestMapping("/get") public void get(HttpServletRequest req,HttpServletResponse res) { res.setContentType("text/plain"); String callbackFunName =req.getParameter("callbackparam");//得到js函數名稱 try { res.getWriter().write(callbackFunName + "([ { name:\"John\"}])"); //返回jsonp資料 } catch (IOException e) { e.printStackTrace(); } } @RequestMapping("/getJsonp") @ResponseBody public JSONPObject getJsonp(String callbackparam){Company company=new Company();company.setAddress("廣州天河華景軟體園");company.setEmail("[email protected]");company.setName("廣州訊動網路可以有限公司");company .setPhone("12345678912"); return new JSONPObject(callbackparam, company); }
AJAX端:
<!DOCTYPE html><html><head><meta charset="utf-8"><script src="http://code.jquery.com/jquery-2.1.3.min.js"></script><script>$(document).ready(function(){$("#but1").click(function(){ $.ajax({url:'http://127.0.0.1:8080/DevInfoWeb/get',type: "get",async: false,dataType: "jsonp",jsonp: "callbackparam", //服務端用於接收callback調用的function名的參數 jsonpCallback: "success_jsonpCallback", //callback的function名稱,服務端會把名稱和data一起傳遞迴來 success: function(json) { alert(json);},error: function(){alert('Error');}});});$("#but2").click(function(){ $.ajax({url:'http://127.0.0.1:8080/DevInfoWeb/getJsonp',type: "get",async: false,dataType: "jsonp",jsonp: "callbackparam", //服務端用於接收callback調用的function名的參數 jsonpCallback: "success_jsonpCallback", //callback的function名稱,服務端會把名稱和data一起傳遞迴來 success: function(json) { alert(json);},error: function(){alert('Error');}});});});</script></head><body><div id="div1"><h2>使用 jQuery AJAX 來改變文本</h2></div><button id="but1">按鈕1</button> <br/><button id="but2">按鈕2</button></body></html>
參考文章:
http://www.2cto.com/kf/201411/351856.html
http://blog.csdn.net/d8111/article/details/45249871
Ajax+Spring MVC實現跨域請求(JSONP)