一.什么是跨域
跨域问题来源于浏览器的同源策略,浏览器为了提高网站的安全性,在发送ajax请求时,只有在当前页面地址与请求地址的协议+域名+端口号相同时才允许访问,否则会被拦截。
协议即通信协议,比如我们现在常见的http和https,如果当前页面地址使用http协议,请求的地址使用https协议,那么这个请求就存在跨域问题。
域名即网站网址,如baidu.com,360.com存在跨域。
端口号即域名对应的服务器的监听端口,这个我们一般是看不到的,因为一般服务器都使用80端口,浏览器默认为80端口,所以不需要在域名后再写出端口号。当8080端口发出的请求为80端口时,也存在跨域。
在前后端分离后,请求数据时跨域问题出现的越来越多,如何解决呢?
二.解决跨域的方法
解决跨域的常用方法有三种,分别为使用代理(如nginx),CORS(跨域资源共享),jsonp。
1.使用代理(nginx)
因为跨域限制是存在于浏览器的,不存在于服务器,所以我们可以使用服务器来请求数据,再返回给浏览器,他的原理比较类似于我们在node开发环境下的代理。现在最常用的代理服务器应该是nginx,这是一个反向代理服务器(反向代理代理服务器,正向代理代理用户)。我们可以使用它来代理转发请求。例如当前页面为https://39.107.104.52:80,但我们请求的服务器使用http协议并监听3000端口,很明显存在跨域问题,可在nginx配置文件中进行如下配置,当nginx匹配到/user和/goods开头的请求时,会将请求转发到http://39.107.104.52:3000。在浏览器中我们可以发现我们请求的地址仍然是同源的,请求成功。
2.CORS(跨域资源共享)
cors的原理是在服务器端设置http响应头,允许浏览器进行跨域请求。下面以java为例:
设置之后我们就可以直接进行跨域请求,这种方法使用较多。
3.jsonp
jsonp的原理是浏览器在引入javascript不受跨域限制,例如我们在https://39.107.104.52:80中引入<script src="http://39.107.104.52:3000/abc.js"></script>,这样是完全可以的,所以我们可以使用script标签来请求数据。大部分的框架中都对jsonp的请求方式进行了封装,使用方法不再细说。
不常用的也有三种,在这里仍然介绍一下,有iframe,window.name,flash。
4.iframe
解决方案就是用window.location对象的hash属性,利用JS改变hash值网页不会刷新,可以这样实现通过JS访问hash值来做到通信,大体就是AB网站各嵌入一个对方网站的iframe,然后通过连续不断的监听hash值的变化来进行通信。比如A网站通过改变B网站iframe的hash后,B网站监听到hash的变化后就进行处理,这种方式需要开发者可以控制两个网站的代码。
5.window.name
window.name是一种解决跨域数据传输的新技术,通过在iframe中加载一个跨域的HTML文件,并且在HTML文件中设置window.name的值为需要传给接受者的数据,接收者就可以取得到window.name的值并且返回,比较关键的是同源策略的影响对location的控制不受限制,所以需要加载一个代理的页面来让发送页面读取window.name.
6.使用flash
原理是JavaScript将数据提交给本域下的 Flash,通过 Flash 中转去访问其他域的接口,只需要其他域的根目录下有一个crossdomain.xml文件,文件中设置允许所有域名或允许本域访问即可。