一、定义
同源:端口协议域名一致,当客户端打开百度,谷歌两个页面,百度的页面执行一个脚本的时候,会检查该脚本是否属于哪个页面,只有跟百度同源的脚本才会执行,否则会给控制台抛出异常
二、作用
为了安全,防止跨站请求攻击等
三、避免同源策略
1、DOM同源策略的规避
a、hash
因为hash的改变并不会引起页面的刷新同时可以通过 window.onhashchange事件监听到hash的改变,所以可以通过hash来跨域传递数据。
b、document.domain
若两个文档的域相同则可以获取对方的DOM对象,并且可以通过设置 document.domain 的值来让两个文档的域保持一致,但是 document.domain 并不是可以设置任何值,只能设置为当前域的超域
c、window.name
window.name有一个特性,即使当前窗口的地址改变了window.name的值也不会改变。可以利用这一特性来进行跨域,步骤如下:
通过iframe加载需要获取数据的地址
在加载的文件上将数据设置到window.name上
数据获取完成后将iframe的地址设置为当前文档同域
通过DOM操作拿到window.name上的数据
d、window.postMessage
以上几种跨域的方法都属于破解行为,而postMessage是H5为跨域提供的解决方法。
3、Ajax同源策略的规避
a、jsonp
虽然跨域限制了Ajax请求,但是却并不影响跨域引用脚本。jsonp只支持GET请求。
<script src="http://example.com/index.php?arg=val1&jsonp=callback"/>
<script>
callback(data){
console.log(data); // 上面的加载完成之后就会打印出后台传过来的数据 "数据"
}
</script>
<?php
echo $_GET['jsonp'] . '(' . '数据' . ')';
?>
上面的 index.php 接口返回的是一段调用 函数的js代码 callback(data),其中data就是接口要返回的数据。而这个callback是事先在页面上写好的处理数据的回调函数,并且回调函数的名称通过URL参数的形式传递给了后端接口,这样就完成了一次跨域。
b、CROS
django框架,使用django-cors-headers扩展,添加应用,
INSTALLED_APPS = (
...
'corsheaders',
...
)
中间层设置
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
]
添加白名单
# CORS
CORS_ORIGIN_WHITELIST = (
'127.0.0.1:8080',
'localhost:8080',
'www.meiduo.site:8080',
'api.meiduo.site:8000'
)
CORS_ALLOW_CREDENTIALS = True # 允许携带cookie
凡是出现在白名单中的域名,都可以访问后端接口
CORS_ALLOW_CREDENTIALS 指明在跨域访问中,后端是否支持对cookie的操作。