前端跨域问题的解决方案

跨域是浏览器的一种安全策略,是浏览器自身做的限制,不允许用户访问不同域名或端口或协议的网站数据。

只有域名(主域名【一级域名】和二级域名)、端口号、协议 完全相同的时候,才允许通信。

# 那么,如何解决跨域问题?

* 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插件。。。

  此方法仅适合在自己的电脑上玩。。啊哈哈哈哈

--------------------------------------------------------------------------------------------------------------

5月27日补充:

由于最近工作遇到跨域解决方案,特地回来补充一下

 8:使用nginx做反向代理。

 9:charles代理工具也可以实现跨域请求数据。(ubantu系统下面)charles的安装方法:http://www.cnblogs.com/summer0319/p/6904163.html

————————————————————————

当然,解决跨域问题还有其他的方法,以后学到了在补充。

以上内容仅仅用来总结记录,有不正确的地方望多指教,互相学习^_^

原文地址:https://www.cnblogs.com/summer0319/p/6443462.html