浏览器的同源策略
一、同源的三个条件
1、域名(二级域名与一级域名之间也算是不同源)
2、端口
3、协议
二、同源策略的意义
浏览器基于用户的隐私安全目的,
防止恶意网站窃取数据(只是浏览器有这个同源策略设置,但是用命令行curl请求某个跨域地址时能得到相应结果),
不允许不同域名的网站之间互相调用ajax XHR对象,
只是不允许XHR对象,对其他的图片、js脚本、css脚本还是可以通过标签跨域调用。
所以css/js/img可以跨域请求(即引用),AJAX不能请求跨域的资源。
同源策略会限制以下三种行为:
1、cookie、localStorage和indexDB无法读取
2、DOM无法获得
3、AJAX 请求无效(可以发送,但浏览器会拒绝接受响应)。
三、跨域访问的四种方式
1、JSONP实现跨域
JSONP(json with padding)方式, 通过script标签请求资源,允许用户在scr地址中传递一个callback参数(callback=abc)即将预先定义好的回调函数名以查询字符串的形式传递给服务端,服务端收到请求后会将要返回的数据用这个callback参数(abc)包裹住再返回,即将请求传入的参数abc作为函数名来包裹住要返回的JSON数据,比如abc(JSON),这样客户端在收到服务端返回的abc(JSON)文件后默认用JS解析执行。通过JSONP就可以随意定制自己的函数来自动处理返回数据了。
jsonp的原理
虽然浏览器默认禁止了跨域访问,但并不禁止在页面中script标签引用其他域下的JS文件,比如线上jquery库,
并可以自由执行引入的JS文件中的function(包括操作cookie、Dom等等)。
根据这一点,可以方便地通过动态创建script节点的方法来实现完全跨域的通信。
jsonp的缺点
1、安全问题,src引用是开放的,所以jsonp的资源都被所有人访问到。
解决方法是用jsonp中的token参数,通过A域和B域共用同一套cookie来验证A的身份。
2、只能用GET方式不能用POST方式获取数据
因为是基于scr引用的,引用是get请求。
3、可被注入恶意代码如?callback=alert(1);
这问题只能用正则过滤字符串的方法解决,过滤callback后的内容不能有括号之类的条件
jsonp代码实现
1.定义数据处理函数
appendHtml(){
xxxxx
}
2、创建script标签,src的地址执行后端接口,最后加个参数callback=appendHtml.如:
var script=document.createElement('script')
script.src="http://127.0.0.1/getNews?callback=appendHtml"
3、服务端在收到请求后,解析参数,计算返还数据,输出 appendHtml(data) 字符串。
4.前台页面收到服务端返回的appendHtml(data)字符串所构建的script标签,页面加载这个script标签时做为js执行。
此时会调用appendHtml()函数,将data做为参数。
注意:JSONP实现的前提是后端必须有JSONP的API接口,即后端有将前端传入的参数作为函数名包裹数据返回js文件的逻辑。
2、CORS 跨域资源共享 Cross-Origin Resource Sharing
CORS允许浏览器向跨域服务器发出XMLHttpRequest请求,突破了AJAX只能同源使用的限制。CORS需要浏览器和服务器同时支持,目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。CORS原理:浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。只要服务器实现了CORS接口,就可以跨源通信。
header("Accept-Control-Allow-Origin","*")//允许所有源发起的请求
如果Origin指定的源,不在服务端许可范围内,服务器会返回一个正常的HTTP回应。
但这个响应头信息没有包含Access-Control-Allow-Origin字段。
浏览器接收后就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。
这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。
如果Origin指定的域名在许可范围内,服务器返回的响应,响应头会包含以下信息字段
Access-Control-Allow-Origin: http://api.bob.com
//允许来自源http://api.bob.com的访问,如果是*则代表允许来自所有源的访问
3、HTML5跨文档通信API window.postMessage
HTML5中最酷的新功能之一就是 跨文档消息传输Cross Document Messaging。 下一代浏览器都将支持这个功能。Facebook已经使用了这个功能,用postMessage支持基于web的实时消息传递。
举例,父窗口aaa.com向子窗口bbb.com发消息,调用postMessage方法如下:
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');
第一个参数是具体的信息内容(支持任意类型),
第二个参数是接收消息目标窗口的源origin(协议 + 域名 + 端口)也可以设为*,表示不限制域名,向所有窗口发送。
子窗口向父窗口发送消息的写法如下:
window.opener.postMessage('Nice to see you', 'http://aaa.com');
父窗口和子窗口都可以通过message事件,监听对方的消息:
window.addEventListener('message', function(event) {
console.log(e.data);
},false);
4、降域 实现iframe窗口跨域访问 实现不同子域页面cookies共享
当两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain来实现iframe窗口相互访问或设置cookie。降域方式只适用于同一站点下不同子域名共享cookie或者iframe页面中嵌套的子域名页面之间的访问。降域不适用访问LocalStorage 和 IndexedDB,postMessage()方法可访问LocalStorage。
document.domain = 'example.com';
服务器也可以在设置 Cookie 的时候,指定 Cookie 的所属域名为一级域名以后二级域名和三级域名不用做任何设置,都可以读取这个Cookie。比如.example.com。
Set-Cookie: key=value; domain=.example.com; path=/
相关文章
- CentOS编译安装PHP7.1.21环境
0.安装一大堆必备的东西 先执行 yum install -y epel-release yum install -y libmcrypt-devel 再执行 yum -y install gcc
- aof恢复与rdb服务器迁移
一、不小心flushall或flushdb了怎么办??? 只有aof还不够。 因为如果发生重写,aof文件里就什么都没有了。 所以要及时shutdown nosave,防止aof重写!!! 然后将a
- 递归和分治思想
一、斐波那契数列 1 1 2 3 5 8 13 21 34 55 89 144 ...... 我们可以用数学函数来定义: |0,当n = 0 F(n) = |1,当n = 1
- solr性能优化
一、简介 Solr性能优化是一个很复杂的任务,也是一个长期与之斗争的过程。在开始之前,首先要对影响Solr性能的基本因素有个大致的认知。影响Solr性能的一个主要因素就是内存。Solr需要有足够的内
- 虚拟环境-virtualenv
在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.4。所有第三方的包都会被pip安装到Python3的site-packages目录下。 如果我们要同时开发多个应用程序,那
随机推荐
- CentOS编译安装PHP7.1.21环境
0.安装一大堆必备的东西 先执行 yum install -y epel-release yum install -y libmcrypt-devel 再执行 yum -y install gcc
- aof恢复与rdb服务器迁移
一、不小心flushall或flushdb了怎么办??? 只有aof还不够。 因为如果发生重写,aof文件里就什么都没有了。 所以要及时shutdown nosave,防止aof重写!!! 然后将a
- 递归和分治思想
一、斐波那契数列 1 1 2 3 5 8 13 21 34 55 89 144 ...... 我们可以用数学函数来定义: |0,当n = 0 F(n) = |1,当n = 1
- solr性能优化
一、简介 Solr性能优化是一个很复杂的任务,也是一个长期与之斗争的过程。在开始之前,首先要对影响Solr性能的基本因素有个大致的认知。影响Solr性能的一个主要因素就是内存。Solr需要有足够的内
- 虚拟环境-virtualenv
在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.4。所有第三方的包都会被pip安装到Python3的site-packages目录下。 如果我们要同时开发多个应用程序,那