浏览器同源策略的行为限制以及规避方法

本文参考自阮一峰老师的文章链接在此http://www.ruanyifeng.com/blog/2016/04/cors.html
一、简单介绍同源策略,即三个相同:
	协议相同,域名相同,端口相同。
二、同源策略主要带来三个方面的行为限制:
	1、cookie,localstorage和IndexDB无法读取
	2、DOM无法获取
	3、Ajax请求不能发送
三、规避方法
	1、cookie的读取: 如果两个网页的一级域名一样,二级域名不同。此时可以通过设置document.domain来共享cookie,举个栗子:
	    A网页域名:https:\\a.example.com B网页域名:https:\\b.example.com
	    此时A、B网页js脚本同时设置document.domain = "example.com";
	    现在A页面设置cookie: docuemnt.cookie = "title=hello";
	    此时B页面就可以通过 document.cookie读取到A页面设置的cookie。
	还可以在服务器设置cookie的时候指定cookie所属域名为一级域名,这样在二级、三级域名下就不用做任何设置就可以读取到这个cookie
   	注意事项:
	    1、这种方式只适用于一级域名相同
	    2、只适用于cookie和iframe,localstorage与IndexDB无法使用。
	2、localstorage和IndexDB读取
	   通过H5的postMessage读写其他窗口的localstorage.举个例子
 	   父窗口https://a.com 子窗口https://b.com
           父窗口向子窗口发送消息:
           var win = document.getElementsByTagName('iframe')[0].contentWindow;
           var obj = { name: 'Jack' };
           win.postMessage(JSON.stringify({key: 'storage', data: obj}), 'http://bbb.com');
           子窗口写入父窗口的localStorage
           window.onmessage = function(e){
               if(e.orgin !== "https://b.com"){
                  return;
               }
           var data = JSON.parse(e.data);
	   localstorage.setItem(data.key,JSON.stringify(data.data));
	  }
	3、DOM的获取
	    三种规避方法:1、片段识别符;2、window.name;3、window.postMessage
	    1、片段识别符
	    片段识别符值的是url的#后面的部分,这一部分的改变不会引起页面的刷新,但这一个变化可以通过window.onhaschange监听到。因此父窗口可以
把信息写到子窗口的片段标识符中。如:
	    父窗口发送信息
               var src = orginURL + "#" + data;       
		document.getElementById("myIFrame").src = src;

            子窗口接受信息
	       window.onhaschange = function(){
		   var message = window.location.hash;
	       }
	    同样地子窗口也可以改变父窗口片段标识符
	    2、window.name
    		window.name:不管是否同源,只要在同一个窗口,前一个网页设置了,后一个网页就可以读取到
		父窗口先打开一个子窗口,载入一个不同源的网页,该网页将信息写入window.name属性。
		    window.name = data;
	        接着,子窗口跳回一个与主窗口同域的网址。
		   location = 'http://parent.url.com/xxx.html';
		然后,主窗口就可以读取子窗口的window.name了。
		   var data = document.getElementById('myFrame').contentWindow.name;
	    这种方法的优点是,window.name容量很大,可以放置非常长的字符串;缺点是必须监听子窗口window.name属性的变化,影响网页性能。
	    3、postMessage
		此方法可参考localstorag。
	4、Ajax
	   1、jsop
		基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回
	    客户端代码:
	<script>
    	function mycall(data){
        	console.log(data);
    	}
   	 function addScriptTag(src) {
        	var script = document.createElement("script");
        	script.setAttribute("type", "text/javascript");
       		script.src = src;
        	document.body.appendChild(script);
    	}
    	addScriptTag('http://127.0.0.1:3000/?callback=mycall');
	</script>
	服务器端为node.js代码:
	app.get('/',function(req,res){
   		var callback = req.query.callback;
   	 	var data = 11;
   	 	res.send(callback+"("+data+")");
   	 	res.end();
	});
2、websocket
		WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
下面是一个例子,浏览器发出的WebSocket请求的头信息。
		GET /chat HTTP/1.1
		Host: server.example.com
		Upgrade: websocket
		Connection: Upgrade
		Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
		Sec-WebSocket-Protocol: chat, superchat
		Sec-WebSocket-Version: 13
		Origin: http://example.com
上面代码中,有一个字段是Origin,表示该请求的请求源(origin),即发自哪个域名。
正是因为有了Origin这个字段,所以WebSocket才没有实行同源政策。因为服务器可以根据这个字段,判断是否许可本次通信。如果该域名在白名单内,服务器就会做出如下回应。


		HTTP/1.1 101 Switching Protocols
		Upgrade: websocket
		Connection: Upgrade
		Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
		Sec-WebSocket-Protocol: chat
	3、CORS
	是解决ajax跨域的根本方法,具体请参考阮一峰老师的http://www.ruanyifeng.com/blog/2016/04/cors.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值