跨域是浏览器的一种安全策略,是浏览器自身做的限制,不允许用户访问不同域名或端口或协议的网站数据。
只有域名(主域名【一级域名】和二级域名)、端口号、协议 完全相同的时候,才允许通信。
# 那么,如何解决跨域问题?
* 1:动态创建script标签
- 使用jQuery的ajax请求时,当参数传入的是jsonp,使用的就是这种方法
1 <script> 2 function fuc(a){ 3 console.log(a.name); 4 } 5 </script> 6 <script src="http://api.study.com/02_jsonp.php?callback=fuc"></script>
<?php header(‘Content-Type:text/html;charset=utf-8‘); /*处理业务逻辑 返回数据给第三方过的的接口*/ $callback = $_GET[‘callback‘]; $json = ‘{"name":"cxh","age":"18"}‘; echo $callback.‘(‘.$json.‘)‘; //给接收的函数一个参数,并返回到页面 ?>
* 2:使用HTML5 的 postMessage
1 <iframe id="ifr" src="b.com/index.html"></iframe> 2 <script type="text/javascript"> 3 window.onload = function() { 4 var ifr = document.getElementById(‘ifr‘); 5 var targetOrigin = ‘http://b.com‘; // 若写成‘http://b.com/c/proxy.html‘效果一样 6 // 若写成‘http://c.com‘就不会执行postMessage了 7 ifr.contentWindow.postMessage(‘I was there!‘, targetOrigin); 8 }; 9 </script>
1 <script type="text/javascript"> 2 window.addEventListener(‘message‘, function(event){ 3 // 通过origin属性判断消息来源地址 4 if (event.origin == ‘http://a.com‘) { 5 alert(event.data); // 弹出"I was there!" 6 alert(event.source); // 对a.com、index.html中window对象的引用 7 // 但由于同源策略,这里event.source不可以访问window对象 8 } 9 }, false); 10 </script>
* 3:jsonp
原理:前端先将一个实现定义好的函数名放给服务端,服务端接受这个函数,然后拼接 ‘(参数)’返回到浏览器。
他是一个前后端配合的结果。
但是有些网站不是公开的数据,并不知道他的已经定义好的函数名是什么
1 <script src="js/jquery.min.js"></script> 2 <script> 3 $.ajax({ 4 type:‘get‘, 5 url:‘http://api.study.com/jquery_jsonp.php‘, 6 dataType:‘jsonp‘, 7 success:function(data){ 8 console.log(data); 9 } 10 }); 11 </script>
* 4:顶级域名相同时的跨域问题,可以使用这些方式
(1)document.domain + iframe
"http://aaa.kuayu.com/" 中的文件可以在JavaScript中,使用top关键字访问到它的上一级元素(也就是引入他的b文件)中的元素。此时页面显示的效果是b文件中的p段落变为黄色
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 body { 8 color: red; 9 } 10 </style> 11 </head> 12 <body> 13 aaaaaaaaaaa 14 </body> 15 </html> 16 <script> 17 document.domain = ‘kuayu.com‘; 18 top.document.getElementsByTagName(‘p‘)[0].style.color = ‘yellow‘; 19 </script>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 body { 8 color: green; 9 } 10 </style> 11 </head> 12 <body> 13 <p>bbbbbbbbbbbb</p> 14 15 <iframe src="http://aaa.kuayu.com/" frameborder="0"></iframe> 16 17 </body> 18 </html> 19 20 <script> 21 22 document.domain = ‘kuayu.com‘; 23 </script>
(2)domain.name = 顶级域名
(3)document.name + iframe
实现思路:给a页面添加一个全局属性name;
在b页面引入a页面,并且在iframe加载完毕之后修改他的url,是他引入一个本地的页面。
此时在b页面通过iframe.contentWindow.name获取的就是a页面的数据
1 <script> 2 var iframe = document.querySelector(‘iframe‘); 3 iframe.contentWindow.name = 111; 4 iframe.onload = function(){ 5 this.src = ‘c.html‘; 6 this.onload = null; 7 } 8 9 setTimeout(function(){ 10 var name = iframe.contentWindow.name; 11 alert(name); 12 },200); 13 14 15 </script>
1 <script> 2 window.name=‘a页面的数据‘ 3 </script>
(4)document.hash + iframe
hash也就是锚点
可以通过hash传递数据
1 <body> 2 <p>bbbbbbbbbbbb</p> 3 4 <iframe src="http://aaa.kuayu.com/#name=hahaha" frameborder="0"></iframe> 5 // 此时hash值name=hahaha 可以传递到a页面,也就是在按页面可以取到b页面传递给她的值。使用这是种方式可以实现数据的跨域传递。 6 </body>
(5)window.postMessage()
5: 在服务器实现跨域的方法(反向代理)
以Apache的配置为例
1:修改Apache的配置文件
#LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
放开注释
2: 修改httpd-vhosts.conf文件,给自己的项目 添加两行
ProxyRequests Off 开启反向代理
ProxyPass /api http://api.botue.com 起一个别名
6:服务端 实现反向代理 (与服务器不同)
1 <?php 2 header(‘Content-Type : application/json‘); 3 4 $result = file_get_contents( ‘跨域的地址‘ ); 5 6 echo $result; 7 ?>
在页面使用XMLHTTPRequest发送请求,可以获取php后台返回出去的跨域的数据
7:在浏览器安装cors插件。。。
此方法仅适合在自己的电脑上玩。。啊哈哈哈哈
————————————————————————
当然,解决跨域问题还有其他的方法,以后学到了在补充。
以上内容仅仅用来总结记录,有不正确的地方望多指教,互相学习^_^
原文:http://www.cnblogs.com/summer0319/p/6443462.html