需要跨域的三种情况:
- 页面和其打开的新窗口的数据传递
- 多窗口之间消息传递
- 页面与嵌套的iframe消息传递
实现跨域的几种方法:
1.window.name
如a.com网站想通过JS获取b.com网站的数据
- 在a.com网站添加一个空HTML页。名称为:http://a.com/null.html
- 在a.com网站需要获取数据页面(如:http://a.com/getDomainData.html)内容如下:
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml" > 3 <head> 4 <title>跨域获取数据</title> 5 <script type="text/javascript"> 6 function domainData(url, fn) 7 { 8 var isFirst = true; 9 var iframe = document.createElement('iframe'); 10 iframe.style.display = 'none'; 11 var loadfn = function(){ 12 if(isFirst){ 13 iframe.contentWindow.location = 'http://a.com/null.html'; 14 isFirst = false; 15 } else { 16 fn(iframe.contentWindow.name); 17 iframe.contentWindow.document.write(''); 18 iframe.contentWindow.close(); 19 document.body.removeChild(iframe); 20 iframe.src = ''; 21 iframe = null; 22 } 23 }; 24 iframe.src = url; 25 if(iframe.attachEvent){ 26 iframe.attachEvent('onload', loadfn); 27 } else { 28 iframe.onload = loadfn; 29 } 30 31 document.body.appendChild(iframe); 32 } 33 </script> 34 </head> 35 <body> 37 </body> 38 <script type="text/javascript"> 39 domainData('http://b.com/data.html', function(data){ 40 alert(data); 41 }); 42 </script> 43 </html>
- 在b.com中添加获取数据页面 如:http://b.com/data.html 内容需包含:
1 <script> 2 window.name = '需要跨域传递的数据'; 3 </script>
- 访问 http://a.com/getDomainData.html 就可返回 http://b.com/data.html 中的window.name中的数据了。
2.window.location.hash
location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.href=url就可以直接将页面重定向url。而location.hash则可以用来获取或设置页面的标签值。比如http://domain/#admin的location.hash="#admin"。利用这个属性值可以做一个非常有意义的事情。
3.window.domain=" "
4.flash
5.html5 postMessage
6.jsonp
7.服务器代理:XMLHttpRequest代理文件
之前在某厂的面试中遇到过jsonp的问题,现在总结一下。
所谓的jsonp技术也就是动态创建script标签,把src地址设置为你的请求文件,通过src的callback函数,在服务器得到响应,返回相应的json数据,并且在服务器端执行该相同名称的函数。
因为同源策略,只有同一个域名下的文件才可以互相访问,详见下表:
编号 | URL | 说明 | 是否允许通信 |
1 |
同一域名下 |
允许 |
|
2 |
同一域名下不同文件夹 |
允许 |
|
3 |
同一域名,不同端口 |
不允许 |
|
4 |
同一域名,不同协议 |
不允许 |
|
5 |
域名和域名对应ip |
不允许 |
|
6 |
主域相同,子域不同 |
不允许 |
|
7 |
同一域名,不同二级域名(同上) |
不允许(cookie这种情况下也不允许访问) |
|
8 |
不同域名 |
不允许 |
1 <script type="text/javascript"> 2 function createScript(str){ 3 var oScript=document.createElement('script'); 4 oScript.type='text/javascript'; 5 oScript.src=str; 6 document.getElementsByTagName('head')[0].append(oScript); 7 8 } 9 function json(data){ 10 console.log(data.name) 11 } 12 </script> 13 <script type="text/javascript" src="http://www.paxst.com/index.php?id=1202&update=0811"></script>
1 json({name:'paxster'})
客户端的函数名称和服务器端函数名称一致,服务器端执行json函数。
页面代理实现跨域:
要实现跨域,第一步需要①A.com/a.html请求到③B.com/b.html;第二步需要B.com/b.html返回数据到A.com/a.html
通过②proxy.html来做中间桥梁,实现①和③的跨域。
首先通过最内层②来链接桥梁,③属于②的子页面,可以传递参数,所以把②的需要的内容请求到①;
b.html内嵌proxy.html是通过一段类似下面这样的代码:
1 <iframe id=”proxy” src=”a.com/proxy.html” name=”proxy” frameborder=”0″ width=”0″ height=”0″></iframe>
这个iframe的src属性b.html是有权限控制的。如果它把src设置成a.com/proxy.html?args=XXX,也就是给url加 一个查询字符串,proxy.html内的js是可以读取到的。对的,这个url的查询字符串就是b.html和proxy.html之间通信的桥梁,美 中不足的是每次通信都要重写一次url造成一次网络请求,这有时会对服务器及页面的运行效率产生很大的影响。
当proxy.html拿到a.html发送过来的数据后把这个数据 写入window.name中,然后跳转到b.com下面的代理页面,我们这里假设是bproxy.html。bproxy.html读取到 window.name值后,通知给它父页面b.html就简单了