SpringMVC解决跨域请求问题——CORS

        js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议域名端口有任何一个不同,都被当作是不同的域。

1. 简介

        CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
        它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

2. 请求过程

Preflight Request:

然后服务器端给我们返回一个Preflight Response

3. 通用实现

 跨域请求分为两种情况,一种是cookie跨域一种是非cookie跨域

3.1 cookie跨域

3.1.1 服务端

只需要在方法中给response添加两个头信息即可

response.setHeader("Access-Control-Allow-Origin", "http://localhost:9105"); 
response.setHeader("Access-Control-Allow-Credentials", "true");

注意:

1)Access-Control-Allow-Origin是HTML5中定义的一种解决资源跨域的策略。他是通过服务器端返回带有Access-Control-Allow-Origin标识的Response header,用来解决资源的跨域权限问题。

扫描二维码关注公众号,回复: 9334654 查看本文章

2)Access-Control-Allow-Origin的value也可以是*,表示接受所有的跨域请求。

3)当Access-Control-Allow-Origin的value为*的时候,其所在的方法不能操作cookie

 4)CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。另一方面,开发者必须在AJAX请求中打开withCredentials属性。否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。

5)Access-Control-Allow-Credentials头信息是可选设置,当其所在的方法不涉及对cookie的操作,那么这句话可以不写,同时客户端也不必添加({'withCredentials':true}

3.1.2 客户端(JS)

客户端的请求不变,但是需要加入一个对象信息({'withCredentials':true}),请求信息如下

$http.get("http://localhost:9107/cart/addGoodsToCartList.do?itemId="+$scope.sku.id+"&num="+$scope.num,{'withCredentials':true})

3.2 非cookie跨域

非cookie的实现比较简单,只需要在服务端添加如下头信息即可

response.setHeader("Access-Control-Allow-Origin", "http://localhost:9105"); 

注意:这里的域名可以用*代替,表示允许所有的跨域请求

4. SpringMVC跨域注解——CrossOrigin

springMVC的版本在4.2或以上版本,可以使用注解实现跨域, 我们只需要在需要跨域的方法上添加注解@CrossOrigin即可

@CrossOrigin有两个比较重要的属性

1)origins,对应于Access-Control-Allow-Origin

2)allowCredentials,对应Access-Control-Allow-Credentials

使用方法如下:

原理同上

1)当是cookie跨域的时候,两个属性都需要,且域名不能用*代替,但是,在MVC中,allowCredentials的缺省值就是true,所以,不管是cookie跨域还是非cookie跨域,都可以只写origins属性。

2)当是非跨域请求的时候,只需要origins属性即可,同时域名可以用*代替,表示所有的跨域请求

发布了205 篇原创文章 · 获赞 9 · 访问量 7932

猜你喜欢

转载自blog.csdn.net/weixin_43318134/article/details/104331512