方法1. jsonp實現ajax跨域訪問示例
jsp代碼:
<body> <input type="button" onclick="testJsonp();" value="TestJsonP"> </body>
js代碼:
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代碼:
@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; }
幾個注意點:
1. jsonp只支持GET方式的請求,無論ajax中的type配置成何種方式,都會在默認以GET方式發送請求。無法滿足restful方式的請求。
2. ajax中的jsonp的標簽名要與服務端的接收標簽參數一致。本例中都設置為'callback'.
3. 若想傳遞一個json格式的js對象到服務器,可以使用JSON.stringify()方法將js對象轉化為json字符串,賦值到某個變量。在服務器端獲取這個變量的值通過json工具,將該字符串轉化為java對象。
方法2. 在服務器端放開訪問權限,使允許接收ajax訪問
前端代碼不需修改。
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)