同源策略
1.什么是JavaScript的同源策略?
- 同源策略是客户端脚本(尤其是JavaScript)中重要的安全度量标准。它最早出自Netscape Navigator 2.0,目的是防止某个文档或脚本从多个不同源装载。
- 同源是指:协议、域名、端口号——完全相同。
- 同源策略是一种安全协议,指一段脚本只能读取同一来源的窗口和文档的属性。
协议
:http/https协议
域名
:ip地址或是ip地址对应的域名
端口号
:80/443默认端口号
2.为什么有同源限制?
- 同源策略的目的就是限制不同源的document或者脚本之间的相互访问,以免造成干扰和混乱。
- 举例:比如一个黑客,他利用
iframe
把真正的银行登录页面嵌到他的页面上,当你使用用户名、密码登录时,他的页面就可以通过JavaScript读取到你表单input中的内容,这样用户名、密码就被盗取了。 - 在普通的JavaScript应用中,我们可以修改
frame
中的href
或者是iframe
中的src
,以实现get方式的跨域提交,但是却不能访问跨域
的frame/iframe中的内容。 - 而在
Ajax
中,它通过XMLHTTPRequest
进行异步交互,这个对象能够与远程的服务器进行信息交互,而且更危险的是:XMLHTTP是一个纯粹的JavaScript对象,这样的交互过程,是在后台进行的,不被用户察觉,因此,XMLHTTP实际上已经突破了原有的JavaScript的安全限制。 - 如果我们又想利用XMLHTTP的无刷新异步交互能力,又不愿意公然突破JavaScript的安全策略,可以选的方案就是给XMLHTTP加上严格的同源限制。
- iframe的限制还仅仅是不能访问跨域HTMLDOM中的数据,而XMLHTTP则根本上限制了跨域请求的提交。
/* iframe 用于在网页内显示网页 */
<iframe src="demo_iframe.htm" width="200" height="200"></iframe>
3. 非同源受到的限制?
1.无法读取非同源网页的 Cookie、LocalStorage 和 IndexDB。
2.无法接触非同源网页的 DOM。
3.无法向非同源地址发送AJAX请求(可以发送,但浏览器拒绝接受响应)。
4.避免同源策略
JSON 和 动态脚本标记
<script
type="text/javascript"
src="https://baidu.com/search?username=123&password=456"
>
// 当JavaScript代码动态的插入script标记时,浏览器会访问src中的url,这样会导致将查询字符串中的信息发送服务器。
</script>
5.AJAX请求跨域
jsonp实现跨域的原理
1.利用script标签的跨域能力请求数据
2.script标签的src属性会把请求回来的数据当成js来执行
3.利用script标签的特性,可以然后端返回一个函数调用,并把数据作为参数传递到前端。
浏览器出于安全考虑,限制了js跨域能力
但 link img iframe script 标签都能跨域拿到资源
浏览器不会限制标签的跨域。
只能发get
请求
<body>
<button class="btn">请求数据</button>
<!-- <script src="./data/jsonp.php?wd=666"></script> -->
<!-- 先不写,需要的时候创建 动态创建script标签-->
<script>
var btn=document.querySelector('.btn')
btn.onclick=function(){
// 需要的是动态创建script标签
var oScript=document.createElement('script')
// 给创建的script标签的src属性赋值,传 数据地址
oScript.src='./data/jsonp.php?wd=888'
// 插入到文档中才会起作用
document.body.appendChild(oScript)
// 在script标签加载完成之后,可以删除
oScript.onload=function(){
document.body.removeChild(oScript)
}
}
//这是一个函数
function test(json){
console.log(json.wd)
}
</script>
</body>
后端的php文件
<?php
// 获取前端传来的数据,get方法
$wd=$_GET['wd'];
// 返回前端自定义函数的调用
echo 'test({a:123,b:456,wd:'.$wd.'})';
?>
jsonp只能发
GET
请求
但兼容性好,简单易用,支持浏览器与服务器双向通信。
CORS 跨资源分享
- Cross-Origin Resource Sharing。它是
W3C
标准,属于跨源AJAX请求的根本方法。 - CORS需要浏览器和服务器同时支持,整个通信过程,都是浏览器自动完成。与普通的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨域,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感知。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨域通信。
- 比jsonp强大,支持所有类型的HTTP请求。JSONP的优势在于支持
老式浏览器
,以及可以向不支持CORS的网络请求数据。
通过设置 Access-Control-Allow-Origin来实现跨域。
// 允许任何来源
header(“Access-Control-Allow-Origin:*”);
其他的跨域方式
1.如果主域相同,可以通过修改document.domain实现跨域。将子域和主域的document.domain设为同一个主域。前提条件是这两个域名必须属于同一个基础域名,而且协议、端口都要一致,否则无法使用。
2.通过修改window.name实现跨域。window对象有一个name属性,该属性有个特征:在一个窗口的生命周期内,窗口中载入的所有页面都是共享一个window.name的,每个页面对window.name都有读写权限。载入过的所有页面的window对象,将持久的存储name属性。
3.在服务器端设置代理模块可以实现跨域。