阿里面试被跨域问题难倒后我决定系统学习一下相关知识

145 阅读3分钟

查看原文

在电话面试时,被阿里面试官问了几个跨域的问题,发现对跨域的了解,第一不成系统,第二太过片面,所以决定好好的学习一下。

什么是跨域?

答:跨域其实就是违背了浏览器的同源策略,所以要想知道什么是跨域,弄明白同源策略就可以了。

既然这样,那请讲一下浏览器的同源策略吧?

答:同源策略得先从同源说起,所谓的同源,需要同时满足三个要求,否则就是跨域。

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,可以通过

var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;

不过在目前大量流行的单页面应用利用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.在本域名下搭建一个代理服务器,所有请求都由本域名所在服务器转发