引言
又是很久没来更新博客了,感觉又要学习一波了,希望在这个十一小长假能够多学些东西,充实自己。
在学习前后端分离的框架中,又一次接触到了跨域,那么我们来分析下,具体什么是跨域问题,以及跨域问题如何解决?
什么是跨域
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。
同源策略又是什么呢?
所谓同源是指域名,协议,端口均相同,则为同源。
举个栗子:
http://www.haozhixin.com/index.html 调用 http://www.haozhixin.com/xxx.do(非跨域)
http://www.haozhixin.com/index.html 调用 http://www.chenmeiom/xxx.do (主域名不同,跨域)
http://www.haozhixin.com:8080/index.html 调用 http://www.haozhixin.com:8081/xxx.do(端口不同:8080/8081,跨域)
http://www.haozhixin.com/index.html 调用 https://www.haozhixin.com/xxx.do (协议不同:http/https,跨域)
注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
怎么解决跨域问题
- 利用jsonp
JSONP(JSON with Padding)是JSON的一种”使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的script 元素是一个例外。利用
function jsonp_fun(){
$.ajax({
url:'http://localhost:8888/other/other.jsp',
type:'GET',//注意jsonp的方式是应用了script引用资源的原理,只支持get请求
data:{'params':'kkk'},
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
success: function(data){
alert("through jsonp,receive data from other domain : "+data.result);
},
error: function(){
alert('fail');
}
});
}
CORS
-
Cross-Origin Resource Sharing (CORS) 是W3c工作草案,它定义了在跨域访问资源时浏览器和服务器之间如何通信。CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否。简单来说,就是同过设置几个http头部来进行请求放行。
-
对一个简单的请求,没有自定义头部,要么使用GET,要么使用POST,它的主体是text/plain,请求用一个名叫Orgin的额外的头部发送。Origin头部包含请求页面的头部(协议,域名,端口),这样服务器可以很容易的决定它是否应该提供响应。
服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。 -
参数说明
Access-Control-Allow-Origin
注释:"表示允许访问的外域URI"
Access-Control-Allow-Origin:*
注释:""*"允许访问任何外域URL"
Access-Control-Allow-Methods
注释:"首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法"
Access-Control-Allow-Credentials
注释:"表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可"
- 具体实现
只要在response中set了以上参数即可。
跨域感知session
跨域感知session需要解决两个问题,第一个是解决跨域问题,第二个是解决跨域cookie传输问题
**跨域和跨域传递cookie是两个不同纬度的问题,**我们依靠上述的方式解决了跨域的问题。但是要做到跨域感知session需要解决在跨域的前提下将cookie也能传上去,这个时候就需要设置另外一个头部 ,我们的cross origin演变为 @CrossOrigin(origins = {""},allowCredentials = “true”,allowedHeaders = "") 使用了allowCredentials后Access-Control-Allow-Credentials头被设置成true,同时前端设置xhrField:{withCredential:true}后,浏览器在ajax请求内带上对应的cookie头部和后端的allowCredentials配合在一起解决跨域传递cookie的问题。由于课程中仅仅使用了get和post的方法,而这两个方法在跨域请求中都是可以用的,因此allowedHeaders可以不加。 另外当设置了allowCredentials = “true"的时候origins = {”*"}就失效了,因为一旦设置了跨域传递cookie就不能再设置接受任何origins了,而springboot的实现方式是返回的allow origin取request内的origin即我们自己对应的html页面的路径。这样就可以做到在哪个origin上使用跨域就允许哪个origin,一样能达到我们想要的效果。
总结
ps:许多浏览器包括safari和最新版本的chrome默认设置都是不支持携带跨域cookie的,即便我们代码写成允许,浏览器底层也做了限制,因此在调试的时候我们可以关闭对应的限制,也可以使用扩展阅读内的其他跨域处理方式
作者:select you from me
来源:CSDN
转载请联系作者获得授权并注明出处。