关于跨域问题,主要用的比较多的是cros跨域和JSONP跨域,JSONP跨域我已经在另外一篇博客中写了,这里主要说的是CORS方式的跨域。
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
基本思路就是在每个http请求的时候添加一些附加的头信息,如:Origin:http://172.18.2.222:8080,Origin字段指的是访问来源,服务器根据这个值,决定是否同意这次请求。如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。(我就在这个地方卡住了,服务器正常返回了数据,但是success回调函数一直捕获不到,总是被error函数捕获。之前一直都不知道有CORS的跨域方式,一直在使用JSONP的方式!!!) 服务器只要指定回应头的:Access-Control-Allow-Origin,就能实现跨域了,这个Access-Control-Allow-Origin的参数设置为Origin的源就可以了。相比JSONP方式,CROS的跨域前端页面和后台不需要做出任何更改。
那么,如何设置服务器的响应头呢?
下面上代码:
package com.fh.plugins.filter;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;@Componentpublic class MyCORSFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) servletResponse; String origin = (String) servletRequest.getRemoteHost()+":"+servletRequest.getRemotePort(); response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization"); response.setHeader("Access-Control-Allow-Credentials","true"); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { }}
定义一个过滤器,为所有的http请求都加上Access-Control-Allow-Origin的头。
web.xml的配置:
cors com.fh.plugins.filter.MyCORSFilter cors /*
前端页面直接使用Ajax请求即可:
$.ajax({ url:URL+"h5Logs/getIMEI.do", type:"get", success:function(data){ //alert(data); var imei_modes = data.split(";"); setCookie("IMEI",imei_modes[1],"d30"); setCookie("user_model",imei_modes[0],"d30"); setCookie("operators",imei_modes[2],"d30"); } });
对于只知道JSONP的跨域方式的同学来说(就是我...), CROS跨域简直太美妙了!!!
参考博客: