jeecg 跨域问题的出现与解决
跨域问题是如何看出来的
对于前后端相互分离的代码来说利用AJAX进行交互,在谷歌控制台上会出现请求头相关的信息,这就说明跨域了。
具体错误信息为:”Access-Control-Allow-Origin” head……
什么是跨域
浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域不同,都是跨域。
为什么会出现跨域
浏览器为了安全起见,因此加入同源政策,因此出现了跨域现象。
什么是同源政策
就是需要满足协议相同、域名相同、端口。
为什么需要同源政策
使用同源政策可以使用户的相关数据更加的安全。那么为什么使用同源政策数据就会更加安全呢?因为使用同源政策可以限制Cookie,也就是说一个网页创建一个Cookie,这样就使的Cookie数据不会在另外网页中显示上一个网页的信息,从而使得数据安全。
同源政策与跨域有什么区别
只要不符合三者中的任意一种就构成跨域问题。因为限制了Cookie与AJAX的请求,所以造成了跨域问题。
利用CORS解决跨域问题
CORS是如何执行的
显示在浏览器中的数据是前端通过AJAX来进行的获取的,那么在这一过程中是如何进行交接的?浏览器需要得到提供者的授权之后才会将其提供的资源分发给消费者。那么,资源的提供者如何进行资源的授权,并将授权的结果告诉浏览器呢?具体的实现其实很简单。如果浏览器 自身提供对CROS的支持,由它发送的请求会携带一个名为“Origin”的报头表明请求页面所在的站点。对于前面我们演示实例中调用Web API获取联系人列表的请求来说,它就具有如下一个“Origin”报头。
CORS是如何解决跨域的
后台可以添加头不信息与前端相互对应,前端发送请求与后台控制的权限进行相互比较,从而获取到后台的相关权限,这样就没有跨域问题了。
CORS权限与后台权限配对关系过程
前端请求分为两种简单请求与复杂请求,在简单请求过程中浏览器会直接发送跨域请求,并在请求头中携带Origin 的header,表明这是一个跨域的请求。在复杂请求过程中浏览器并不会立即执行对应的请求代码,而是会先发送Preflighted requests(预先验证请求),Preflighted requests是一个OPTION请求,用于询问要被跨域访问的服务器,是否允许当前域名下的页面发送跨域的请求。 OPTIONS请求头部中会包含以下头部:Origin、Access-Control-Request-Method、Access-Control-Request-Headers。服务器收到OPTIONS请求后,设置Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers头部与浏览器沟通来判断是否允许这个请求。如果Preflighted requests验证通过,浏览器才会发送真正的跨域请求。过程小结:
- 通过请求的“Origin”报头表示的源站点必须存在于“Access-Control-Allow-Origin”响应报头标识的站点列表中。
- 响应报头“Access-Control-Allow-Methods”不存在,或者预检请求的“Access-Control-Request-Method”报头表示的请求方法在其列表之内。
- 预检请求的“Access-Control-Request-Headers”报头存储的报头名称均在响应报头“Access-Control-Allow-Headers”表示的报头列表之内。
什么简单请求、复杂请求
- Access-Control-Allow-Methods:跨域资源请求允许采用的HTTP方法列表。
- Access-Control-Allow-Headers:跨域资源请求允许携带的自定义报头列表。
- Access-Control-Max-Age:浏览器可以将响应结果进行缓存的时间(单位为秒),这样可以让浏览器避免频繁地发送预检请求。
Jeecg开发平台中如何解决
由于JEECG平台没有针对跨域中的复杂请求做相应的处理(OPTION)因此需要加入如下代码:
BaseController.java
/** * add by wangyong * 为了支持H5页面跨域访问,对options请求统一进行处理 */ @RequestMapping(method = RequestMethod.OPTIONS, value = "/**") public void commonOptions(HttpServletResponse theHttpServletResponse) { theHttpServletResponse.addHeader("Access-Control-Allow-Origin", "*"); theHttpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); theHttpServletResponse.addHeader("Access-Control-Allow-Headers", "content-type,X-AUTH-TOKEN"); }
RestAuthToken
//TODO:跨域配置 待定 // 为了支持h5页面跨域访问,对options请求放行 if (RequestMethod.OPTIONS.name().equals(request.getMethod()) && requestPath.startsWith("/rest/api")) { return true; }
Web.xml
<!-- add by wangyong 为了支持h5页面跨域访问,对options请求放行 -->
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>