背景:
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("123456@qq.com"); 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