跨域问题的直接原因是浏览器存在同源策略,浏览器同源指的是:两个页面的协议、端口和主机相同,则两个页面具有相同的源。IE下满足协议、主机相同,就认为是同源。
想象一下,如果没有同源策略,谁都可以修改你站点上的内容,读取你的cookie,后果难以想象
前端跨域的几种方式
修改document.domain
document.domain 用来获取当前网页的域名,document.domain可以被赋值
document.domain只能修改成当前域名的主域名或者基础域名,如当前域名是b.360.cn,那么document.domain只能改成主域名www.360.cn或者基础域名360.cn,改为其它值会提示“参数无效”
如 a.360.cn/x.html 和 b.360.cn/y.html 都将document.domain 改为360.cn 后,两个页面就可以跨域通信了
前提条件:两个域名必须属于同一个基础域名且协议端口一致
隐患:当a.360.cn 遭到攻击后,b.360.cn会有安全隐患
动态创建script
script 不受同源策略限制,在a.360.cn页面中引入b.360.cn的js文件,就可以操作a.360.cn下的cookie、DOM等
通过location.hash传参
a、b、c三个页面,a、c页面同源,b是需要跨域的页面,a页面创建一个iframe指向b页面,b页面根据parent.location.hash 的值去做相应的操作,操作完成后修改parent.location.hash 的值告诉a,a监听自己的hash变化,IE、chrome下,b页面无法直接修改parent.location.hash,需要借助与a同源的c页面,具体做法是,b页面创建iframe指向c页面,b页面改变自己的hash,c页面读取b页面的parent.location.hash去修改a页面的hash,a、c页面同源,c页面可以修改a页面的hash,即parent.parent.location.hash
通过window.name传参
a、b、c三个页面,a、c页面同源,b是需要跨域的页面,a页面创建iframe指向b页面,b页面将数据赋值给window.name,接着修改iframe的src指向c页面,a、c页面同源,参考document.domain方法取得c页面window.name的值,为了安全,获取数据后销毁iframe
POSTMessage
a、b两个页面分别属于http://a.360.cn和http://b.360.cn,两个页面通信
// a.360.cn/a.html内容 <iframe id="iFr" src="b.360.cn/b.html"></iframe> var iFrame = document.getElementById(‘iFr‘); var targetOrigin = ‘http://b.360.cn/b.html‘; iFrame.contentWindow.postMessage(‘message from http://a.360.cn‘, targetOrigin); // b.360.cn/b.html内容 window.addEventListener(‘message‘, function(event){ // 安全起见,必须验证消息来源 if(event.origin === ‘http://a.360.cn‘){ alert(event.data); // ‘message from http://a.360.cn‘ } })
JSONP
动态创建script标签加载数据,前端将回调函数名传给服务端,服务端返回回调函数,函数参数是请求过来的数据,将返回值插入页面会自动执行
1)安全问题
2)要确定jsonp请求是否成功并不容易