Web页面的跨域问题产生原因是企图使用JS脚本读写不同域的JS作用域。问题根源来自JavaScript的同源策略:出于安全考虑,Javascript限制来自不同源的web页面JS脚本之间进行交互。否则就会出现各种获取用户私密数据的问题。
1、document.domain
它只能只能解决一个域名下的不同二级域名页面跨域,例如person.aa.com与book.aa.com,可以将book.aa.com用iframe添加到 person.aa.com的某个页面下,在person.aa.com和iframe里面都加上document.domain = "aa.com"。
2、Jsonp
Jsonp可以解决XmlHttpRequest请求不能跨域的限制,原理是通过动态创建一个<script> 元素来请求一段JS脚本,让这段脚本在页面作用域里执行,迂回实现类似Ajax的请求。
1 //加载js文件 2 function load_script(url, callback){ 3 var head = document.getElementsByTagName('head')[0]; 4 var script = document.createElement('script'); 5 script.type = 'text/javascript'; 6 script.src = url; 7 script.onload = script.onreadystatechange = function(){ 8 if((!this.readyState||this.readyState === "loaded"||this.readyState === "complete")){ 9 callback && callback(); 10 // Handle memory leak in IE 11 script.onload = script.onreadystatechange = null; 12 if ( head && script.parentNode ) { 13 head.removeChild( script ); 14 } 15 } 16 }; 17 head.insertBefore( script, head.firstChild ); 18 }
3、用HTML5的API
HTML5提供了一个可以让我们跨域通信的API:postMessage,支持的浏览器有 Internet Explorer 8.0+, Chrome 2.0+、Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+。window.postMessage方法被调用时,目标窗口的message事件即被触发,这样可以实现不同域直接的信息交流。
假设A页面中包含iframe B页面
1 var winB = window.frames[0]; 2 3 winB.postMessage('hello iframe', 'http://www.test.com'); 4 5 //B页面(监听message事件、获取信息) 6 7 window.addEventListener('message',function(e){ 8 9 // ensure sender's origin 10 11 if(e.origin == 'http://www.aa.com'){ 12 13 console.log('source: ' + e.source); 14 15 console.log('Message Received: ' + e.data); 16 17 } 18 19 },false)
PS. 通信事件没有冒泡.
4、window.name
window.name一般用来获取子窗口:window.frames[windowName];它有个重要特点:一个窗口无论加载什么页面,window.name都保持不变。而这个特点可以用来进行跨域信息传递。例如3个页面分别为A、B、C。A是主页面,里面嵌入了一个iframe:B页面。B页面对window.name进行赋值,接下来重定向到C页面。C页面在另外一个域里面,它的功能就是读取出B页面写入的window.name。
1 <!-- A页面 --> 2 <html> 3 <head> 4 <title> Page A</title> 5 </head> 6 <body> 7 <iframe src=”B.html” /> 8 </body> 9 </html> 10 11 <!-- B页面 --> 12 <html> 13 <head> 14 <title> Page B </title> 15 </head> 16 <body> 17 <script language=”JavaScript”> 18 var a = []; 19 for (var i = 0;i < 10; i++){ 20 a.push(’xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’+i); 21 } 22 window.name= a.join(''); //写入window.name,这里可以写入一个比较大的值 23 window.location.href = ‘http://www.cc.com/C.html’; 24 </script> 25 </body> 26 </html> 27 28 <!-- C页面 --> 29 <html> 30 <head> 31 <title> Page C </title> 32 </head> 33 <body> 34 <script language=”JavaScript”> 35 document.write(window.name);//读出window.name,并写到页面上 36 </script> 37 </body> 38 </html>
可以看到C页面正常输出了B页面写入的window.name。