方法1. jsonp實現ajax跨域訪問示例html
jsp代碼:前端
<body> <input type="button" onclick="testJsonp();" value="TestJsonP"> </body>
js代碼:java
function testJsonp(){ $.ajax({ type : 'GET', dataType : 'jsonp', // 數據類型配置成jsonp jsonp : "callback", //配置jsonp隨機碼標籤,在服務器代碼部分須要用到他來拼接一個json的js對象 url : 'http://127.0.0.1:8001/test', //服務路徑 async : false, data: { "type":'0', }, success : function (response) { if(response.code == 200){ alert('返回成功!'); }else{ alert('服務器異常!'); } }, error : function (){ alert('服務器異常!'); } }); }
java代碼:web
@RequestMapping(value = "/test", method = RequestMethod.GET) public @ResponseBody String testJsonp(@RequestParam(value = "type", defaultValue = "") String type, String callback) { RequestResult data = new RequestResult(); // 配置須要返回的結果 data.setCode(200); data.setMessage("success"); // 接收參數callback名稱須要與js中配置的jsonp標籤名一致 String result = callback+"("+JSONObject.fromObject(data).toString()+")";//拼接可執行的js return result; }
幾個注意點:ajax
1. jsonp只支持GET方式的請求,不管ajax中的type配置成何種方式,都會在默認以GET方式發送請求。沒法知足restful方式的請求。spring
2. ajax中的jsonp的標籤名要與服務端的接收標籤參數一致。本例中都設置爲'callback'.json
3. 若想傳遞一個json格式的js對象到服務器,能夠使用JSON.stringify()方法將js對象轉化爲json字符串,賦值到某個變量。在服務器端獲取這個變量的值經過json工具,將該字符串轉化爲java對象。跨域
方法2. 在服務器端放開訪問權限,使容許接收ajax訪問服務器
前端代碼不需修改。restful
java代碼, 在BaseController中加入:
// protected HttpServletRequest request;
protected HttpServletResponse response; // protected HttpSession session; @ModelAttribute public void setReqAndRes(HttpServletRequest request, HttpServletResponse response) { // this.request = request; this.response = response; // this.session = request.getSession(); response.setHeader("Access-Control-Allow-Origin", "*"); } @RequestMapping(value = "/test", method = RequestMethod.GET) public @ResponseBody RequestResult test() { RequestResult result = new RequestResult(); result.setCode(200); result.setMessage("success");
return result; }
說明:ModelAttribute的做用
1)放置在方法的形參上:表示引用Model中的數據
2)放置在方法上面:表示請求該類的每一個Action前都會首先執行它,也能夠將一些準備數據的操做放置在該方法裏面。
這種方式只容許GET方式的請求,沒法知足restful格式的請求。
方法3.終極解決辦法(方法2的升級版)
前端代碼不需修改。
在服務器端寫一個filter,在doFilter方法中全面放開訪問權限,並將此filter配置到web.xml中,或直接使用註解,劃入spring管理。此方法徹底支持restful的ajax跨域請求。
下面給一下spring mvc框架下的一個解決示例(親測可用):
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; @Component("myFilter") public class MyFilter implements Filter { public void destroy() { // System.out.println("過濾器銷燬"); } public void doFilter(ServletRequest request, ServletResponse response1, FilterChain chain) throws IOException, ServletException { // System.out.println("執行過濾操做"); HttpServletResponse response = (HttpServletResponse) response1; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Headers", "User-Agent,Origin,Cache-Control,Content-type,Date,Server,withCredentials,AccessToken"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); response.setHeader("Access-Control-Max-Age", "1209600"); response.setHeader("Access-Control-Expose-Headers", "accesstoken"); response.setHeader("Access-Control-Request-Headers", "accesstoken"); response.setHeader("Expires", "-1"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("pragma", "no-cache"); chain.doFilter(request, response); } public void init(FilterConfig arg0) throws ServletException { // System.out.println("過濾器初始化"); } }
參考文章:
Ajax跨域(jsonp) 調用JAVA後臺 (http://www.cnblogs.com/holdon521/p/5282354.html)
springMVC獲取request和response (http://blog.sina.com.cn/s/blog_7085382f0102v9jg.html)
REST跨域訪問解決CorsFilter (http://blog.csdn.net/u013628152/article/details/49490213)
Spring Boot 過濾器、監聽器 (http://blog.csdn.net/catoop/article/details/50501688)