在电话面试时,被阿里面试官问了几个跨域的问题,发现对跨域的了解,第一不成系统,第二太过片面,所以决定好好的学习一下。
什么是跨域?
答:跨域其实就是违背了浏览器的同源策略,所以要想知道什么是跨域,弄明白同源策略就可以了。
既然这样,那请讲一下浏览器的同源策略吧?
答:同源策略得先从同源说起,所谓的同源,需要同时满足三个要求,否则就是跨域。
1.请求协议相同,比如a网页用的是http协议,那么a网页下的b请求使用https,就不满足同源的要求,可以判定为跨域了。
2.域名(ip)相同(阮一峰大神的博客上说的是域名相同),MDN博客上说是主机相同。这两种说法似乎有点矛盾,因为一个主机上是可以布多个网站的,这里也请看到的大神能指正一下,我也有点模糊。
3.端口相同。
不同网页之间获取cookie,LocalStorage,IndexDB,DOM,以及同一网页下面的AJAX请求,只要违反了以上三点中的任意一点,都是跨域。
有一个需求,两个网页的一级域名相同,二级域名不相同,我想共享cookie,应该怎么做呢?
答:这个时候可以通过将document.domain设置为两个网页共同的父域,来实现共享cookie。这个时候要注意一点,两个域名的端口也会被设置成null。
想操作不同源的网页dom,传输数据怎么办?
在网页中包含一个iframe,想要互相操作dom,目前有以下4种方法。
1.如果两个网页的一级域名相同,可以通过设置document.domain来实现互相获取dom的想法。
2.完全不同源的网页,第一个可以用的方法是在页面的url的#后面添加参数,然后通过window.onhashchange 监听页面的hash改变来获取内容,间接进行dom操作。
比如,你想操作父窗口的url,可以通过parent.location.href= target + "#" + hash;
来操作。
又如,你想操作子窗口的dom,可以通过
1 | var src = originURL + '#' + data; |
不过在目前大量流行的单页面应用利用hash来做路由的情况下,这个方法得谨慎使用。
3.通过改变window.name来实现数据互通。window.name不受跨域的影响,而且可容纳的数据量大,可以通过监听window.name来实现
4.使用windw.postMessage方法。
这个是h5为了解决跨域的问题新添加的一个api,允许跨域不同窗口之间通信。子窗口或者父窗口通过window.postMessage方法向对方发送一个消息,然后对方通过监听message事件,来处理数据。
跨域的情况下ajax请求都有什么好方法啊?
答,这个是有方法的。下面一一列举。
1.JSONP方法。
因为script,iframe,image等不受同源策略的影响,所以可以利用这一点来实现ajax通信。JSONP就是通过动态动态创建script来和服务器通信。
具体的方法是手动创建和插入script标签,然后服务端按照约定将数据通过回掉方法的方式返回过来,返回过来的数据因为是包裹在回掉方法中,因为是js文件,回掉方法会立刻执行。
2.用WebSocket通信。因为WebSOcket具有origin属性,可以通过白名单来决定是否返回数据,从而不受同源策略的影响。
3.服务器端设置Access-Control-Allow-Origin为特定的域名,允许访问。当然也可以设置为*,允许所有域名访问,不过这个比较危险。
4.在本域名下搭建一个代理服务器,所有请求都由本域名所在服务器转发