开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情
前言
跨域是一个会经常遇到的问题,特别是当服务有两个域名时,如你的页面是在a.test.com,然后需要向b.test.com请求数据,这个时候就跨域了。如果直接请求,你会发现浏览器报错了,这个时候就要了解什么是同源策略
1、什么是同源策略?
同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
我们看下一个域名地址的组成
允许跨域加载资源的标签
<img src='xxx'>
<link href='xxx'>
<script src='xxx'>
同源策略只正度浏览器端,浏览器一旦检测到请求的结果的域名不一致后,会堵塞请求结果。
注:跨域请求是可以发去的,但是请求响应response被浏览器堵塞了。
2、跨域解决方案
解决方案有JSONP、CORS、postMessage、websocket、Node中间件代理(两次跨域)、nginx反向代理、window.name + iframe、location.hash + iframe、document.domain + iframe,CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案,JSONP只支持GET请求,JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。不管是Node中间件代理还是nginx反向代理,主要是通过同源策略对服务器不加限制。
接下来,我们一起来了解几个常用的吧。
(1)JSONP
JSONP的原理是利用 <script>
标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以噢~
它的优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性, 不安全可能会遭受XSS攻击。
(2)CORS
CORS是跨域资源共享的缩写,通过在目标域名返回CORS响应头来达到获取该域名的数据的目的,核心就是设置 response header,优点是通过简单的配置就能跨域,缺点是某些古老浏览器不支持CORS或不支持 Credentials。
(3)WebSocket
WebSocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据。同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。
原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
(4)nginx反向代理
实现原理类似于Node中间件代理,需要你搭建一个中转nginx服务器,用于转发请求。
使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
(5)Node中间件代理(两次跨域)
在做代理的时候,我们需要考虑,我们代理的是客户端去请求后台服务器,node 只是作为中间服务来,来承担一些很基本的功能,然后在把服务断返回的数据,也需要经过我们的代理来把数据返回给客户端。这么做的好处是,隐藏真正的服务器请求地址,减少数据的暴露,许多数据都可以在代理那里做个性化的配置。