跨域
同源策略
同源策略(Same origin policy)是一种约定,是一个重要的安全策略,它是浏览器最核心也最基本的安全功能。
目的:同源策略限制了一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互。
这是一个用于隔离潜在恶意文件的重要安全机制。
同源策略只发生在浏览器中,如果不是浏览器的话, 就不会受到同源策略的影响。也就是说,两个服务器直接进行跨域请求是可以进行数据请求的。
同源
两个URL的protocol(协议)、port(端口)、host(主机、域名)都相同,属于同源。
任意一个不同都算作不同源(即跨域)。为了避免csrf跨域请求伪造,请求会被浏览器拦截。
什么是跨域请求
当一台服务器资源从另一台服务器(不同的域名或者端口)请求一个资源或者接口,就会发起一个跨域 HTTP 请求。举个简单的例子,从http://aaa.com/index.html,发送一个 Ajax 请求,请求地址是http://bbb.com/下面的一个接口,这就是发起了一个跨域请求。
请求跨域了,那么请求到底有没有发出去
跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。你可能会疑问明明通过表单的方式可以发起跨域请求,为什么 Ajax 就不会?因为归根结底,跨域是为了阻止用户读取到另一个域名下的内容,Ajax 可以获取响应,浏览器认为这不安全,所以拦截了响应。但是表单并不会获取新的内容,所以可以发起跨域请求。同时也说明了跨域并不能完全阻止 CSRF,因为请求毕竟是发出去了。
如何解决跨域
解决跨域就是通过某些手段来绕过同源策略限制,实现不同服务器之间通信的效果
- 服务端进行设置默认允许某些域名跨域访问
- 从客户端入手想办法绕开同源安全策略
1. jsonp
- 利用 script 标签不受同源策略限制的漏洞,将请求模拟成script标签请求,写入callback回调函数,后台将结果用callback包装返回,回调函数即可得到数据,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。
- JSONP和AJAX相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)
- JSONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性,不安全可能会遭受XSS攻击。
利用script标签的src帮助我们去服务器请求到数据,将数据当作一个JavaScript的函数来执行,并且执行的过程中传入我们需要的json
核心在于我们监听window上的jsonp进行回调时的名称
2. cors
支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案
CORS(Cross-origin resource sharing),跨域资源共享。CORS 其实是浏览器制定的一个规范,浏览器会自动进行 CORS 通信,它的实现则主要在服务端,它通过一些 HTTP Header 来限制可以访问的域,例如页面 A 需要访问 B 服务器上的数据,如果 B 服务器 上声明了允许 A 的域名访问,那么从 A 到 B 的跨域请求就可以完成。对于那些会对服务器数据产生副作用的 HTTP 请求,浏览器会使用 OPTIONS 方法发起 一个预检请求(preflight request),从而可以获知服务器端是否允许该跨域请求,服务器端确认允许后,才会发起实际的请求。在预检请求的返回中,服务器端也可以告知客户端是否需要身份认证信息。我们只需要设置响应头,即可进行跨域请求。
CORS添加header
Response.addHeader(‘Access-Control-Allow-Orgin’ ,‘* ’);
Response.addHeader(‘Access-Control-Allow-Method’,’POST,GET,DELETE,PUT’);
Response.addHeader(‘Access-Control-Allow-Headers’,);
3. @CrossOrigin注解
这个方法仅对Java有用。springboot中,在Controller类上添加一个 @CrossOrigin(origins ="*") 注解就可以实现对当前controller 的跨域访问了,当然这个标签也可以加到方法上,或者直接加到入口类上对所有接口进行跨域处理,注意这个注解只在JDK1.8版本以上才起作用。
4. 使用SpringCloud网关
服务网关(zuul)又称路由中心,用来统一访问所有api接口,维护服务。
Spring Cloud Zuul通过与Spring Cloud Eureka的整合,实现了对服务实例的自动化维护,所以在使用服务路由配置的时候,我们不需要向传统路由配置方式那样去指定具体的服务实例地址,只需要通过Ant模式配置文件参数即可
5. Node中间件代理(两次跨域)
同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。这样的话,我们可以让服务器替我们发送一个请求,请求其他服务器下面的数据。然后我们的页面访问当前服务器下的接口就没有跨域问题了。
6. nginx反向代理
实现原理类似于Node中间件代理,需要你搭建一个中转nginx服务器,用于转发请求。
使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。
实现思路:通过nginx配置一个代理服务器做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
浙公网安备 33010602011771号