跨域出现的原因
同源策略导致跨域,那么什么是同源策略呐,浏览器就同源策略主要针对了接口的请求和DOM查询来做了操作,下面做详细的介绍
什么是同源策略:
- 协议相同
- 域名相同
- 端口相同
与http://www.baidu.com相比,默认端口号为80
协议不同 | https://www.baidu.com |
---|---|
域名不同 | http:// www.baidu.cn |
端口不同 | http:// www.baidu.com:8081 |
其中有一项不同就不是同源
同源策略的目的:是为了保证用户信息的安全,防止恶意的网站窃取数据。如果没有同源策略,A用户在当前中登录了账号,浏览器将cookie保存,这时她又去浏览其他网站,就会直接进入,不用登录,此时的cookie是共享状态的,为了避免出现这种问题,便有了同源策略的说法。
限制范围:如果不同源,有三种行为是受到限制的
- localstorage,cookie,indexDB无法读取
- ajax请求
- Dom不可获取到
虽然以上几种行为会出现某些风险,但有时我们需要有这些行为,那么就来说说怎么实现这几种行为吧。
Cookie
此方法只适用于ifream中的cookie,针对于localStroage和indexDB是不适用的
cookie是浏览器写入服务器的的一段信息,只有同源的网页才可以共享,但是如果两个域名的一级域名相同,二级域名不同,也是可以通过document.domain来共享cookie的。
那么什么叫一级域名什么叫二级域名呐,一级域名又叫顶级域名,类似于www.baidu.com并不是一个一级域名而是个二级域名,一级域名是有字符串组成的域名主体+后缀(类似.com .cn)组成的,所以baidu.com才是一级域名。
二级域名其实是在一级域名的前面加了个字符串类似于qq.baidu.com,二级域名通过设置可以拥有与一级域名相同的功能。有一级域名不一定有二级域名,有二级域名一定有一级域名。
例如现在有两个域名,域名Ahttp://crossdomain.com:9099,域名Bhttp://two.crossdomain.com:9099
document.domain = 'crossdomain.com' //给两个域名设置相同的document.domain
//给A域名设置cookie
document.cookie = 'sid=test'
//B域名获取这个cookie
var allCookie = document.cookie;
另外也可以在服务器中设置cookied的域名为1级域名
Set-Cookie: key=value; domain=.example.com; path=/
这样的话二级域名三级域名都不需要操作就可以拿到cookie
ifream
如果两个网页不同源,就无法拿到对方的DOM。典型的例子是ifream和open.window打开的页面,他们与父页面是没有进行通信的。
如果在父页面想去拿到子页面的dom元素是会报错的,反之也一样,但如果一级域名相同,二级域名不同,则可以通过上面的domain方法设置,避免同源策略,拿到DOM.
对于完全不同源的网站,目前有三种方法,可以解决跨域窗口的通信问题。
-
片段识别符(fragment identifier)
片段标识符是指的例如www.baidu.com#index,指的是#后面的内容,当片段标识符改变时页面不会进行刷新。 -
window.name
浏览器窗口有window.name属性。这个属性的最大特点是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它 -
跨文档通信API(Cross-document messaging)
为了解决这个问题,html5提供了一个新的API跨文档通信api