【百思不得其解】浏览器同源策略

osnot 2014-02-25 11:46:14
如题看了很多关于同源策略的文章,大多数讲解如何跨域访问,一大堆,而我要问的是为何需要同源策略,看了很多文章,下面是比较靠谱的:http://www.91ri.org/7330.html,引用其中的一段话:

在浏览器中,对于标签 <script>、<img>、<iframe>、<link> 等标签都可以跨域加载资源,而不受同源策略的限制。这些带有“src”属性的标签每次加载的时候,实际上是由浏览器发起一个get请求。
不同于XMLHttpRequest的是,通过src属性加载的资源,浏览器是限制了javascript的权限,使其不能够读写返回的内容。对于 XMLHttpRequest来说,它可以访问来自同源对象的内容。但是不能够访问跨域访问资源,所有在ajax开发中尤其需要注意这点在w3c委员会制 定了XMLHttpRequest跨域访问标准。他需要通过目标域返回的HTTP头授权是否允许跨域访问,因为HTTP头对于javascript来说一 般是无法控制的,所以认为这个方案是可行的。


问题1:也就是src加载js的时候是没有同源策略限制的,有且只有当js发出请求(ajax)时才会有同源策略的限制吗?

看到网上讲解同源策略的最多的例子就是:

大家知道,JavaScript可以做很多东西,比如:读取/修改网页中某个值。恩,你现在打开了浏览器,在一 个tab窗口中打开了银行网站,在另外一个tab窗口中打开了一个恶意网站,而那个恶意网站挂了一个的专门修改银行信息的JavaScript,当你访问 这个恶意网站并且执行它JavaScript时,你的银行页面就会被这个JavaScript修改,后果会非常严重!而同源策略就为了防止这种事情发生.
比如说,浏览器的两个tab页中分别打开了http://www.baidu.com/index.html和http: //www.google.com/index.html,其中,JavaScript1和JavaScript3是属于百度的脚本,而 JavaScript2是属于谷歌的脚本,当浏览器的tab1要运行一个脚本时,便会进行同源检查,只有和www.baidu.com同源的脚本才能被执 行,所谓同源,就是指域名、协议、端口相同。所以,tab1只能执行JavaScript1和JavaScript3脚本,而JavaScript2不能 执行,从而防止其他网页对本网页的非法篡改。


问题2:假设没有同源策略,上述例子中第一个例子,我打开一个页面http://www.icbc.com/index.html页面,我又打开了一个http://www.change.com/index.html页面,请问后者如何操作前者的页面?
假设没有同源策略,上述例子中第二个例子,我打开http://www.baidu.com/index.html如何加载google的JavaScript2并且执行?是src吗?


我真心是看不懂,弄不明白,望理解者给点提示或者说明,最好是说的很简单的(我比较笨),谢谢。
...全文
2763 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenyuzixue 2014-10-14
  • 打赏
  • 举报
回复
dagouaofei 2014-07-10
  • 打赏
  • 举报
回复
引用 20 楼 l676331991 的回复:
ajax同源策略的原因想起来啦!我来构造一个如果没有同源策略,ajax请求会有危险的场景: 我们知道,现在很多web应用的身份验证都是通过cookie来维持的,http是无状态的,于是后端催生了session的概念,session必然有id,用来标识当前用户的本次会话之用,session id一般都会放在cookie中,具体session id的生成和防冒用等技术,这里不说,且看cookie。cookie的特性是,每次http请求都会带到服务器上,这样,服务器就可以从中取出sessionID,会话得以保持。 再说说ajax,ajax本身其实就是一次Http请求,自然,ajax也会带上cookie,否则程序员就没办法写出类似ajaxGetUserInfo这种功能。这里问题就来了,如果a.com页面上的js脚本向b.com域发起一个跨域ajax请求,那么,你说浏览器会带上哪个域的cookie呢?自然是b.com域下的!问题来了,既然带的是b.com的域下的cookie,那么认证什么的,自然是看b.com的cookie有什么了。如果恰巧用户此时正在浏览b.com而且登陆了,那恭喜a.com,可以顺顺利利得到b.com返回的内容了,只要进一步挖掘b.com的接口,a.com可以想干啥就干啥啦! 假设你此时正登陆了某宝,同时登陆了某带色的网站b,b网站只要一条跨域ajax,就可以把你账户里的money转走。ajax没有同源策略太恐怖了!!! 你会说,那某宝傻啊,不会判断一下发来的ajax的referer啊,如果referer不是自己站点的,就不开方便之门不就行了。可是,但是,这是ajax第二版规范里的东东,服务端可以设置接受哪些域发起的ajax。况且光凭referer去判断存在很多弊端,比如超链接打开的页面也带referer那怎么办,干脆一个同源策略,阻止的干干净净。由于web的复杂性越来越高,很多时候需要跨域ajax的场景,与其程序员费脑子又是后端代理又是各种歪门邪道的,不如将跨域ajax纳入规范吧,但是安全这一关一定要把紧啊,事关钱财性命! 综上,这就是ajax需要同源策略的原因。
ajax需要同源策略还可以有一个例子,假设我知道csdn发帖的api,那么我可以写一个ajax并调用此api并循环一百亿次,那么csdn就挂了。
osnot 2014-02-25
  • 打赏
  • 举报
回复
引用 2 楼 showbo 的回复:
说白点就是,你加载js你肯定知道js是要干嘛的所以你才会加载 ajax请求资源,有些人家不允许你调用的,肯定不希望你ajax或者iframe引入了 iframe也同样,你引入别人的页面,还想修改成自己的显示方法,谁能乐意
首先谢谢斑竹回复,其次我知道你说的,但是我想问如果没有同源策略,我帖子中的两个例子会如何实现呢?就是第二个问题。
Go 旅城通票 2014-02-25
  • 打赏
  • 举报
回复
说白点就是,你加载js你肯定知道js是要干嘛的所以你才会加载 ajax请求资源,有些人家不允许你调用的,肯定不希望你ajax或者iframe引入了 iframe也同样,你引入别人的页面,还想修改成自己的显示方法,谁能乐意
Go 旅城通票 2014-02-25
  • 打赏
  • 举报
回复
加载js没有同源问题 ajax请求需要被请求的页面允许跨域请求才行,iframe,window.open加载的页面要相互操作有同源问题,不同源不能相互操作
osnot 2014-02-25
  • 打赏
  • 举报
回复
引用 20 楼 l676331991 的回复:
ajax同源策略的原因想起来啦!我来构造一个如果没有同源策略,ajax请求会有危险的场景: ...
这是你说的:“存在同源策略的地方有:跨frame脚本,跨window脚本,cookie访问,XMLHttpRequest请求。”中的cookie访问。 谢谢你,讲解的很详细。我知道为什么存在同源策略了。 结贴了~
l676331991 2014-02-25
  • 打赏
  • 举报
回复
ajax同源策略的原因想起来啦!我来构造一个如果没有同源策略,ajax请求会有危险的场景: 我们知道,现在很多web应用的身份验证都是通过cookie来维持的,http是无状态的,于是后端催生了session的概念,session必然有id,用来标识当前用户的本次会话之用,session id一般都会放在cookie中,具体session id的生成和防冒用等技术,这里不说,且看cookie。cookie的特性是,每次http请求都会带到服务器上,这样,服务器就可以从中取出sessionID,会话得以保持。 再说说ajax,ajax本身其实就是一次Http请求,自然,ajax也会带上cookie,否则程序员就没办法写出类似ajaxGetUserInfo这种功能。这里问题就来了,如果a.com页面上的js脚本向b.com域发起一个跨域ajax请求,那么,你说浏览器会带上哪个域的cookie呢?自然是b.com域下的!问题来了,既然带的是b.com的域下的cookie,那么认证什么的,自然是看b.com的cookie有什么了。如果恰巧用户此时正在浏览b.com而且登陆了,那恭喜a.com,可以顺顺利利得到b.com返回的内容了,只要进一步挖掘b.com的接口,a.com可以想干啥就干啥啦! 假设你此时正登陆了某宝,同时登陆了某带色的网站b,b网站只要一条跨域ajax,就可以把你账户里的money转走。ajax没有同源策略太恐怖了!!! 你会说,那某宝傻啊,不会判断一下发来的ajax的referer啊,如果referer不是自己站点的,就不开方便之门不就行了。可是,但是,这是ajax第二版规范里的东东,服务端可以设置接受哪些域发起的ajax。况且光凭referer去判断存在很多弊端,比如超链接打开的页面也带referer那怎么办,干脆一个同源策略,阻止的干干净净。由于web的复杂性越来越高,很多时候需要跨域ajax的场景,与其程序员费脑子又是后端代理又是各种歪门邪道的,不如将跨域ajax纳入规范吧,但是安全这一关一定要把紧啊,事关钱财性命! 综上,这就是ajax需要同源策略的原因。
osnot 2014-02-25
  • 打赏
  • 举报
回复
引用 17 楼 l676331991 的回复:
我就说嘛,LZ肯定是在想,就算没有同源策略,有什么不安全的么?于是就构造一个场景,假设没有同源策略,会产生哪些安全问题,问题就解决了。 后面的是问我自己的,也算是问各位大大的,突然脑子短路。
我以为我第二个问题已经说得很清楚了,已经打上了前提:“假设没有同源策略,上述例子中...”,的确换成你的说法可能更加让人容易理解。
osnot 2014-02-25
  • 打赏
  • 举报
回复
引用 15 楼 l676331991 的回复:
姑且认为LZ的问题是: “我还是想知道如果没有同源策略,我的第二个例子具体如何进行非法篡改的?” 然后作答了。
其实我就是不明白为什么要设定同源策略这个规则,我要知其然也要知其所以然啊,所以弄不明白原因很别扭,但是你回答我看到了,可以通过window.open()方法来获得打开的网页的句柄,并且操作它,通过这种方式就可以获取别的“源”的信息了,谢谢。 我还知道利用iframe加载可以,不知道还有其他方法吗?
l676331991 2014-02-25
  • 打赏
  • 举报
回复
我就说嘛,LZ肯定是在想,就算没有同源策略,有什么不安全的么?于是就构造一个场景,假设没有同源策略,会产生哪些安全问题,问题就解决了。 后面的是问我自己的,也算是问各位大大的,突然脑子短路。
osnot 2014-02-25
  • 打赏
  • 举报
回复
引用 13 楼 l676331991 的回复:
如果没有同源策略,那么你的第二个例子可以这样: 在http://www.change.com/index.html放上钓鱼的内容,诱导用户在其页面上点击打开http://www.icbc.com/index.html网银页面,这里可以用window.open来打开,同时获得新窗口的句柄。用户看地址栏是“爱存不存”的,乖乖的填上网银的关键信息,然而,孰不知,这个页面的window句柄已被钓鱼页面获取。有窗口句柄可以干什么?这个所谓的句柄就是页面的window对象啊,有了window对象,等于整个页面都是你的了,拦截表单,捕获数据,将账号密码发送到钓鱼网站的后端。。。从此上网都只能直接输入域名来访问了,第三方链接神马的有人敢点么?你只是open了我的页面而已,结果你都可以随意篡改我的前端内容了。 这个逻辑同样适用于被打开页面回过头来修改来源页面的内容,使用window.opener即可获取来源页面的窗口句柄,而且target="_blank"的超链接打开的页面也可以获取window.opener,想想这多么恐怖,一个外链就能引来XSS。 如果两个tab是相互独立的,那自然还是安全的,但是web的特性就是超链接,用户的tab不可能都是自己输入网址打开的,肯定存在某个tab是其他tab的超链接打开的情况,没有同源策略,世界就混乱了。 这段话明显错误,也不知道你从什么网上看到的谬论,如果是这样,那么,那些CDN js托管是怎么办到的?
引用
当浏览器的tab1要运行一个脚本时,便会进行同源检查,只有和www.baidu.com同源的脚本才能被执行
存在同源策略的地方有:跨frame脚本,跨window脚本,cookie访问,XMLHttpRequest请求。 其实XHR第二版已经支持跨域异步请求了,只要后端配合就行。 浏览器为什么不支持ajax跨域呢,脑子抽了一下,突然不理解了,创建一个form然后js脚本submit不照样可以跨域吗?为什么ajax跨域要被限制呢?
你第一段话解决了我的第二个问题,至于你问:

比如说,浏览器的两个tab页中分别打开了http://www.baidu.com/index.html和http: //www.google.com/index.html,其中,JavaScript1和JavaScript3是属于百度的脚本,而 JavaScript2是属于谷歌的脚本,当浏览器的tab1要运行一个脚本时,便会进行同源检查,只有和www.baidu.com同源的脚本才能被执 行,所谓同源,就是指域名、协议、端口相同。所以,tab1只能执行JavaScript1和JavaScript3脚本,而JavaScript2不能 执行,从而防止其他网页对本网页的非法篡改。
来源于哪里?百度随便一搜便是,地址:http://hikin.iteye.com/blog/857573 还有你最后一个问题:

浏览器为什么不支持ajax跨域呢,脑子抽了一下,突然不理解了,创建一个form然后js脚本submit不照样可以跨域吗?为什么ajax跨域要被限制呢?
这是你的问题还是问我?我不会的说。。。
l676331991 2014-02-25
  • 打赏
  • 举报
回复
姑且认为LZ的问题是: “我还是想知道如果没有同源策略,我的第二个例子具体如何进行非法篡改的?” 然后作答了。
l676331991 2014-02-25
  • 打赏
  • 举报
回复
引用
我还是想知道我第二个问题如果没有同源策略,应该如何实现?
楼主的这句话如何理解呢?这到底是在问什么?
l676331991 2014-02-25
  • 打赏
  • 举报
回复
如果没有同源策略,那么你的第二个例子可以这样: 在http://www.change.com/index.html放上钓鱼的内容,诱导用户在其页面上点击打开http://www.icbc.com/index.html网银页面,这里可以用window.open来打开,同时获得新窗口的句柄。用户看地址栏是“爱存不存”的,乖乖的填上网银的关键信息,然而,孰不知,这个页面的window句柄已被钓鱼页面获取。有窗口句柄可以干什么?这个所谓的句柄就是页面的window对象啊,有了window对象,等于整个页面都是你的了,拦截表单,捕获数据,将账号密码发送到钓鱼网站的后端。。。从此上网都只能直接输入域名来访问了,第三方链接神马的有人敢点么?你只是open了我的页面而已,结果你都可以随意篡改我的前端内容了。 这个逻辑同样适用于被打开页面回过头来修改来源页面的内容,使用window.opener即可获取来源页面的窗口句柄,而且target="_blank"的超链接打开的页面也可以获取window.opener,想想这多么恐怖,一个外链就能引来XSS。 如果两个tab是相互独立的,那自然还是安全的,但是web的特性就是超链接,用户的tab不可能都是自己输入网址打开的,肯定存在某个tab是其他tab的超链接打开的情况,没有同源策略,世界就混乱了。 这段话明显错误,也不知道你从什么网上看到的谬论,如果是这样,那么,那些CDN js托管是怎么办到的?
引用
当浏览器的tab1要运行一个脚本时,便会进行同源检查,只有和www.baidu.com同源的脚本才能被执行
存在同源策略的地方有:跨frame脚本,跨window脚本,cookie访问,XMLHttpRequest请求。 其实XHR第二版已经支持跨域异步请求了,只要后端配合就行。 浏览器为什么不支持ajax跨域呢,脑子抽了一下,突然不理解了,创建一个form然后js脚本submit不照样可以跨域吗?为什么ajax跨域要被限制呢?
zhjdg 2014-02-25
  • 打赏
  • 举报
回复
在你能够,找出这些方法或属性后,再研究什么叫同源策略。
zhjdg 2014-02-25
  • 打赏
  • 举报
回复
什么假如没有同源策略。 知不知道: javascript(正确点,寄托在浏览器中的javascript)提供的方法或属性,适用于在不同页面的操作,有那些。 是方法。 <script>、<img>、<iframe>、<link> 是标签,
Go 旅城通票 2014-02-25
  • 打赏
  • 举报
回复
无解。。不能控制的话 要不你就需要做代理页面,代理页面服务器端xhr捉取跨域的页面内容输出(自己处理里面的css文件,图片文件地址,直接引用别人网站的),然后iframe加载你的代理页面就可以,不过这种方法操作起来不是一般的麻烦
osnot 2014-02-25
  • 打赏
  • 举报
回复
引用 7 楼 showbo 的回复:
1可以用jsonp来替代ajax,虽然被请求的页面可以设置access-control-allow-origin为*允许跨域,但是xhr对象在IE8-下用的对象不一样,兼容性不是很好 iframe/window.open这种如果你没有权限修改页面内容,没办法实现互相操作。如果你能控制,可以通过插入iframe做代理来实现跨域,参考:javascript通过iframe加载同源代理页面实现顶级域跨域操作
谢谢,我还是想知道我第二个问题如果没有同源策略,应该如何实现?
osnot 2014-02-25
  • 打赏
  • 举报
回复
Go 旅城通票 2014-02-25
  • 打赏
  • 举报
回复
1可以用jsonp来替代ajax,虽然被请求的页面可以设置access-control-allow-origin为*允许跨域,但是xhr对象在IE8-下用的对象不一样,兼容性不是很好 iframe/window.open这种如果你没有权限修改页面内容,没办法实现互相操作。如果你能控制,可以通过插入iframe做代理来实现跨域,参考:javascript通过iframe加载同源代理页面实现顶级域跨域操作
加载更多回复(1)

87,910

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧