摘要:三哪些会受到同源策略限制对于浏览器来说,除了会受到同源策略的限制外,浏览器加载的一些第三方插件也有各自的同源策略。九的现代浏览器允许脚本直连一个地址而不管同源策略。
一、Origin(源)
源由下面三个部分组成:
域名
端口
协议
两个 URL ,只有这三个都相同的情况下,才可以称为同源。
下来就以 "http://www.example.com/page.html" 这个链接来比较说明:
对比URL | 结果 | 原因 |
---|---|---|
http://m.example.com/page.html | 不同源 | 域名不同 |
https://www.example.com/page.... | 不同源 | 协议不同 |
http://www.example.com:8080/page.html | 不同源 | 端口不同 |
http://www.example.com/page3.... | 同源 | 同域名,同端口,同协议 |
浏览器的同源策略是一种安全功能,同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。
三、哪些会受到同源策略限制对于浏览器来说,除了DOM、Cookie、XMLHttpRequest 会受到同源策略的限制外,浏览器加载的一些第三方插件也有各自的同源策略。最常见的一些插件如 Flash ,有自己的控制策略。
所以,想要体验下,同源策略限制,你就可以写一个ajax 请求,比如127.0.0.1:80 要请求127.0.0.1:8080 的 a.js ;
127.0.0.1:80 里的index.html
Document 另一个页面
然后就会报错了,出现了同源策略限制了。
四、什么是跨域呢说的跨域,其实呢就是跨源。而跨域是一个统称,通过上面的我们知道了,因为同源策略,不同源之间,不能进行交互。那么跨域就是解决不同源之间发起请求、请求数据、发送数据、通信等交互问题解决方法的统称。
在浏览器中,、 、、、 等标签都可以跨域加载资源,而不受同源策略的限制,通过 src 属性加载的资源,浏览器都会发起一个 GET 请求,但是浏览器限制了 JavaScript 的权限,使用js不能读、写加载的内容。
这句话什么意思呢,其实就是,你可以通过这几个标签来跨域加载资源,但是,发起的GET请求 返回的数据,通过 js 获取不到。
注意:通过 标签获取 js 文件里的全局属性,方法等,可以通过 js 读取到。是因为这些都是挂载在 window对象上的,看下面:
127.0.0.1 index.html
Document
127.0.0.1:8080 index.js
function say(){ var app = document.getElementById("app"); app.innerHTML = "我是被挂载到window对象上的方法,所以可以获取到我!"; }五、jsonp跨域
到底什么是jsonp 跨域呢?其实,jsonp 跟 json 两者没有什么关系,也没有什么相似的地方,大家都知道json 是一种数据格式,而jsonp 之所以被称为jsonp,我认为跟它发出请求后,一般得到的,都是json格式数据有关吧。
上面说过了,、 、、、这些标签都可以发起跨域请求,其中的 标签都熟悉吧,经常用来加载 js 文件。jsonp就是利用了这个标签。
不知道大家有没有疑问啊,既然这些标签都能发起跨域请求,那么为啥只用 标签可以请求到数据呢?其实呢,关键就在于,再请求得到数据后,遇到js代码,就会解析执行。理解这个也不难,你在js文件里写的代码,肯定是要被执行的。
比如127.0.0.1 里的index.html 页面加载了一个 :
function say(){ console.log("666"); } say();
当打开127.0.0.1/index.html页面时,标签发起了一个对index.js 的 GET 请求,得到数据后,js引擎开始解析执行,然后say方法就被执行了,这时,控制台就会输出 "666";
那么jsonp就是利用了这点了。先来写一个jsonp实例吧。
127.0.0.1 jsonp.html:
Document JSONP
然后是 127.0.0.1:8080 index.php文件:
"zdx", "sex" => "man", "age" => 18 ); $callback = $_GET["callback"]; echo $callback . "(" . json_encode($data) . ")"; ?>
当访问jsonp.html时,其中的发起一个请求,并发送了一个名为callback参数,值为字符串"say"。然后index.php 把传进来的 say 和要发送的 data 进行字符串拼接,json_encode 函数就是把 数据转成json 格式的。然后这个请求就返回了:say({"name":"zdx","sex":"man","age":18});然后 得到这个数据后,就会解析执行 say 函数了。
所以明白了吧,jsonp 是需要后端 支持的,需要配套使用,然后关于jsonp 是存在安全风险的,传过来的数据直接执行,那么只要改掉同名的函数,那么想怎么操作数据都可以了。还可以修改参数值,对传到服务器的数据进行修改,从而攻击服务器。
注意:此方法只能发起GET请求,通过jsonp发送的请求,会随带 cookie 一起发送。
六、CORS跨域(跨域资源共享)CORS(Cross-Origin Resource Sharing,跨源资源共享)定义了在必须访问跨源资源时,浏览器与服务器应该如何沟通。CORS 背后的基本思想,就是使用自定义的 HTTP 头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
注意:此方法IE8以下完全不支持,IE8-10部分支持。
这需要服务器 和前端配合, 或者 后端 和 前端配合。
可以看看阮老师的:跨域资源共享 CORS 详解
这里以 php 为例,只需在需要被请求的 php 文件里加上一个响应头部 header("Access-Control-Allow-Origin:http://127.0.0.1"),后面的域名就是允许请求的域名。这里就是表示允许来自http://127.0.0.1所有的请求。
127.0.0.1:8080 index.php:
然后就是前端了。IE10及以上、Firefox 3.5+、Safari 4+、Chrome、iOS版 Safari和 Android平台中的 WebKit都通过 XMLHttpRequest 对象实现了对 CORS 的原生支持。
127.0.0.1:80 index.html:
Document 另一个页面
而IE8 - IE9是通过XDR对象实现 CORS 的。
基于XDR的 index.html 代码如下:
XDR对象实现CORS XDR对象实现CORS
注意:CORS可以发起 GET、POST请求,但是发送的请求,默认不会随带 cookie 一起发送, 也不会接受后端发过来的 cookie;
要想随带cookie 一起发送。
需要在127.0.0.1:8080 index.php添加 header("Access-Control-Allow-Credentials:true");头部,然后在127.0.0.1:80 index.html中var xhr = new XMLHttpRequest();后面添加xhr.withCredentials = true;
同源策略认为域和子域属于不同的域,如:
child1.a.com 与 a.com,
child1.a.com 与 child2.a.com,
xxx.child1.a.com 与 child1.a.com
两两不同源,可以通过设置 document.domain="a.com",浏览器就会认为它们都是同一个源。想要实现以上任意两个页面之间的通信,两个页面必须都设置documen.damain="a.com"。
此方式的特点:
只能在父域名与子域名之间使用,且将 xxx.child1.a.com域名设置为a.com后,不能再设置成child1.a.com。
存在安全性问题,当一个站点被攻击后,另一个站点会引起安全漏洞。
这种方法只适用于 Cookie 和 iframe 窗口。
下面来模拟一下,在a.com 与 child1.a.com 之间通信。如果要在本机测试,请自行更改host 等,访问的都是本机80端口,这里就不在累述了。
a.com index.html
Document 主页面
child1.a.com index.php
child1.a.com index1.html
Document child
注意:此方法可以发起 GET、POST 请求,发起的请求不会随带 cookie 一起发送,也不能接受后端发过来的 cookie
八、HTML5的postMessage方法这是html5 新加的方法。
这个方法允许一个页面的脚本发送数据到另一个页面的脚本中,不管脚本是否跨域。在一个window对象上调用postMessage()会异步的触发window上的onmessage事件,然后触发定义好的事件处理方法。一个页面上的脚本仍然不能直接访问另外一个页面上的方法或者变量,但是他们可以安全的通过消息传递技术交流。
比如说父页面为127.0.0.1:80 的页面,传送数据给 127.0.0.1:8080 的子页面:
127.0.0.1:80 index.html
Document 父页面
127.0.0.1:8080 index.html
Document 子页面
然后访问:127.0.0.1:80/index.html,就得到想要的结果了,这方法通常用来进行两个窗口通信。
九、HTML5的WebSocket现代浏览器允许脚本直连一个WebSocket地址而不管同源策略。然而,使用WebSocket URI的时候,在请求中插入Origin头就可以标识脚本请求的源。为了确保跨站安全,WebSocket服务器必须根据允许接受请求的白名单中的源列表比较头数据。
这个因为需要后端的支持,而且比较复杂,这里就不举例子了,感兴趣的可以去查阅资料。
这里贴一个阮老师的websocket教程吧:WebSocket 教程
十、window.namewindow对象有一个name属性,该属性有一个特征:即在一个窗口的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每一个页面对window.name都有读写的权限,window.name是持久的存在于一个窗口载入的所有页面中的,并不会因为新的页面的载入而被重置。
因此,就可以利用此特性,进行跨域通信。
127.0.0.1:80 index.html
Document window.name
127.0.0.1:8080 index.html
Document
这时,访问127.0.0.1:80/index.html,跳转到的127.0.0.1:8080/index.html就能接受传过来的数据了。
十一、location.hash原理是利用location.hash来进行传值。在url: http://a.com#helloword中的‘#helloworld’就是location.hash。
127.0.0.1:80 index.html
Document window.name
127.0.0.1:8080 index.html
Document
这时,访问127.0.0.1:80/index.html,跳转到的127.0.0.1:8080/index.html就能接受传过来的数据了。
十二、proxy 跨域这个完全是后端的实现,我就不说了,我也搞不懂,也没意义。哈哈。
这里说的还是皮毛,这些跨域方案只是工具,怎么利用,就看你了。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/97993.html
摘要:扯了这么多,自然不是为了吹水,而是要为了引出前端开发的一个重要的知识点同源策略什么是同源策略出于保护用户信息安全的目的,现在的浏览器都会实施同源策略这个政策,所谓同源策略指的是不同源的客户端脚本在没有明确授权情况下,不允许读写对方的资源。 导语你家的小孩带了他的朋友来你们的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿东西吃你自然是不会阻止,但是如果你家小孩的朋友人品不行,乱拿东西吃、...
摘要:扯了这么多,自然不是为了吹水,而是要为了引出前端开发的一个重要的知识点同源策略什么是同源策略出于保护用户信息安全的目的,现在的浏览器都会实施同源策略这个政策,所谓同源策略指的是不同源的客户端脚本在没有明确授权情况下,不允许读写对方的资源。 导语你家的小孩带了他的朋友来你们的家里玩,你家的小孩如果要在自家屋里拿玩具玩、拿东西吃你自然是不会阻止,但是如果你家小孩的朋友人品不行,乱拿东西吃、...
摘要:上节我们讲了同源策略,这节我们讲讲如何跨域。当这些从的脚本执行出错,因为违背了同源策略为了保证用户信息不被泄露,错误信息不会显示出来,取而代之只会返回一个。 前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每...
摘要:同源策略是什么同源策略是浏览器的一个安全功能,不同源的数据禁止访问。或许你可以说验证,在浏览器没有同源策略的情况下这些都可以绕过去。总结同源策略是蛮好的,防御了大部分的攻击。 前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思...
阅读 2343·2021-11-11 16:54
阅读 2595·2021-09-26 09:47
阅读 3977·2021-09-08 09:36
阅读 2727·2021-07-25 21:37
阅读 926·2019-08-30 15:54
阅读 2540·2019-08-30 14:22
阅读 3245·2019-08-30 13:57
阅读 2558·2019-08-29 17:17