跨域指的是不同源的网页在信息共享上的限制,是浏览器的安全策略,而不是http协议的一部分,跨站请求会被浏览器限制,或者跨站请求被允许但是返回结果被浏览器拦截。首先同源指的是:协议名,域名,端口号,均相同,有一个不同即为跨域。跨域的网页在以下操作中均受限:
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。
其他可以参见参考文献1。本文仅讨论无法发送Ajax请求时的跨域如何解决。解决方法如下:
- JSONP
- CORS
- nginx
- nodejs
- Websocket
JSONP
Jsonp的原理是利用<img><script><iframe>等标签的src属性可以绕过跨域限制来进行跨域操作,具体操作是,通过 <script> 标签指向一个需要访问的地址并提供一个回调函数来接收数据当需要通讯时。
<script src="http://domain/api?param1=a¶m2=b&callback=jsonp"></script>
<script>
function jsonp(data) {
console.log(data)
}
</script>CORS
CORS(跨域资源共享)是一种机制,它使用额外的http头来告诉浏览器,让运行在一个origin (domain)上的web应用被准许访问来自不同源服务器上指定的资源。(来自mdn)只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置。 需注意的是:由于同源策略的限制,所读取的cookie为跨域请求接口所在域的cookie,而非当前页 若后端设置成功,前端浏览器控制台则不会出现跨域报错信息,反之,说明没设成功。
分为简单请求和复杂请求(多一个由浏览器根据发送的请求自动加上的OPTIONS预检请求,不用人为干涉),详见参考文献3.
Nginx
跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域。
NodeJS
跨域原理: node中间件实现跨域代理,原理大致与nginx相同,都是通过启一个代理服务器,实现数据的转发,也可以通过设置cookieDomainRewrite参数修改响应头中cookie中域名,实现当前域的cookie写入,方便接口登录认证。
Websocket
WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。
原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
参考文献:
1.www.ruanyifeng.com/blog/2016/0…
3.developer.mozilla.org/zh-CN/docs/…
4.segmentfault.com/a/119000001…