美文网首页程序员
浏览器跨域访问解决方案

浏览器跨域访问解决方案

作者: 茹茹茹茹茹茹欧尼_ | 来源:发表于2017-07-15 22:35 被阅读0次

跨域的概念


跨域大家都知道,不同地址,不同端口,不同级别,不同协议都会构成跨域。例如:about.haorooms.comwww.haorooms.com都会构成跨域。总结起来只要协议、域名、端口有任何一个不同,都被当作是不同的域。下面举例,每两个一组。

 URL 说明 是否允许通信
http://www.haorooms.com/a.js
http://www.haorooms.com/b.js 同一域名下 允许

http://www.haorooms.com/lab/a.js
http://www.haorooms.com/script/b.js 同一域名下不同文件夹 允许

http://www.haorooms.com:8000/a.js
http://www.haorooms.com/b.js 同一域名,不同端口 不允许

http://www.haorooms.com/a.js
https://www.haorooms.com/b.js 同一域名,不同协议 不允许

http://www.haorooms.com/a.js
http://60.32.92.74/b.js 域名和域名对应ip 不允许

http://www.haorooms.com/a.js
http://about.haorooms.com/b.js 主域相同,子域不同 不允许

http://www.haorooms.com/a.js
http://haorooms.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)

http://www.hao123.com/a.js
http://www.haorooms.com/b.js 不同域名 不允许

解决跨域的方案


上一篇文章,我写了window.postMessage,是一种跨域的解决方案。今天再介绍几个。

CORS跨域资源共享

众所周知,我们之前跨域很多时候用的是jsonp的方式,jsonp的方式我后面介绍。下面说说CORS跨域和jsonp跨域的优势:

CORS与JSONP相比,无疑更为先进、方便和可靠。

1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。[低版本IE7以下不支持,要支持IE7还是要用jsonp方式]

CORS的使用

CORS要前后端同时做配置。

1、首先我们来看前端。

纯js的ajax请求。

<script type="text/javascript">
     var xhr = new XMLHttpRequest(); //ie6以下用new
 ActiveXObject("Microsoft.XMLHTTP");可以做能力判断。
     xhr.open("GET", "/haorooms",true); 
    xhr.send();
</script>

以上的haorooms是相对路径,如果我们要使用CORS,相关Ajax代码可能如下所示:

<script type="text/javascript"> 
  var xhr = new XMLHttpRequest();//ie6以下用new 
ActiveXObject("Microsoft.XMLHTTP");可以做能力判断。
   xhr.open("GET","http://www.haorooms.com/CORS",true); 
xhr.send();
</script>

当然,你也可以用jquery的ajax进行。

2、后端或者服务器端的配置

下面我们主要介绍Apache和PHP里的设置方法。

Apache:Apache需要使用mod_headers模块来激活HTTP头的设置,它默认是激活的。你只需要在Apache配置文件的 < Directory >, < Location>, < Files >或< VirtualHost>的配置里加入以下内容即可:

Header set Access-Control-Allow-Origin * 

PHP:只需要使用如下的代码设置即可。

<?php header("Access-Control-Allow-Origin:*"); 

以上的配置的含义是允许任何域发起的请求都可以获取当前服务器的数据。当然,这样有很大的危险性,恶意站点可能通过XSS攻击我们的服务器。所以我们应该尽量有针对性的对限制安全的来源,例如下面的设置使得只有www.xxxxxxx.com这个域才能跨域访问服务器的API。

 Access-Control-Allow-Origin: 
http://www.xxxxxxx.com 

通过jsonp跨域


jsonp跨域也需要前后端配合使用。一般后端设置callback ,前端给后台接口中传一个callback 就可以。

例如前端代码:

<script type="text/javascript"> 
      function dosomething(jsondata){ 
          //处理获得的json数据 
      }
</script>
<script src="http://haorooms.com/data.php?callback=dosomething"></script>

后台代码:

<?php$callback = $_GET['callback'];//得到回调函数名
$data = array('a','b','c');//要返回的数据
echo $callback.'('.json_encode($data).')';//输出?>

假如你用ajax方式进行jsonp跨域

/* 
//简写形式,效果相同
 $.getJSON("url跨域地址", {
        参数,要把callback作为参数传到后端
},
 function(data){
               //结构处理
         },"jsonp"); */
 $.ajax({ 
        type : "get",
         url : "跨域地址",
        dataType : "jsonp",//数据类型为jsonp
        jsonp: "callback",//服务端用于接收callback调用的function名的参数【后台接受什么参数,我们就传什么参数】我们上面设置是callback 

success : function(data){ 
        //结果处理 
}, 
error:function(data){ 
            console.log(data); 
        } 
});

通过修改document.domain来跨子域


我们只需要在跨域的两个页面中设置document.domain就可以了。修改document.domain的方法只适用于不同子域的框架间的交互。

<iframe id = "iframe" 
src="http://haorooms.com/b.html" onload = "test()">
</iframe>
<script type="text/javascript"> 
    document.domain = 'haorooms.com';//设置成主域
     function test(){ 
alert(document.getElementById('
iframe').contentWindow);//contentWindow 可取得子窗口的 window 对象
 }
</script>

2、在页面http:// haorooms.com/b.html 中设置document.domain
<script type="text/javascript"> document.domain = 'haorooms.com';//在iframe载入这个页面也设置document.domain,使之与主页面的document.domain相同</script>

使用window.name来进行跨域
原理:
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的。
方法:
假如有三个页面。
a.com/app.html:应用页面。a.com/proxy.html:代理文件,一般是一个没有任何内容的html文件,需要和应用页面在同一域下。b.com/data.html:应用页面需要获取数据的页面,可称为数据页面。

1、在应用页面(a.com/app.html)中创建一个iframe,把其src指向数据页面(b.com/data.html)。
数据页面会把数据附加到这个iframe的window.name上,data.html代码如下:
<script type="text/javascript"> window.name = 'I was there!'; // 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右 // 数据格式可以自定义,如json、字符串</script>

2、在应用页面(a.com/app.html)中监听iframe的onload事件,在此事件中设置这个iframe的src指向本地域的代理文件(代理文件和应用页面在同一域下,所以可以相互通信)。
app.html部分代码如下:
<script type="text/javascript"> var state = 0, iframe = document.createElement('iframe'), loadfn = function() { if (state === 1) { var data = iframe.contentWindow.name; // 读取数据 alert(data); //弹出'I was there!' } else if (state === 0) { state = 1; iframe.contentWindow.location = "http://a.com/proxy.html"; // 设置的代理文件 } }; iframe.src = 'http://b.com/data.html'; if (iframe.attachEvent) { iframe.attachEvent('onload', loadfn); } else { iframe.onload = loadfn; } document.body.appendChild(iframe);</script>

3、获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)。
<script type="text/javascript"> iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe);</script>

相关文章

  • H5跨域访问

    跨域访问是源于浏览器的同源策略而引申出来的概念 1、先了解什么是同源策略和跨域访问 同源策略、跨域解决方案 - R...

  • 跨域

    参考资料 HTTP访问控制(CORS)跨域解决方案跨域详解

  • 浏览器跨域及其解决方案

    title: 浏览器跨域及其解决方案author: Maydate: 20220428 什么是跨域跨域的表现解决跨...

  • CORS 原理

    CORS 是跨域的一种解决方案,服务端在响应头设置允许跨域的origin,浏览器便可以访问加载这些资源。另外还引入...

  • 跨域分析

    浏览器为什么会产生跨域访问安全问题 浏览器的限制 浏览器为了安全考虑会限制不同域下的请求资源访问. 跨域的简单请求...

  • 前端使用nginx解决浏览器跨域

    一. 浏览器跨域 浏览器跨域限制,学名浏览器同源策略,其实是为了数据安全,由Netscape提出来限制浏览器访问跨...

  • JS跨域及解决方案

    <转>详解跨域(最全的解决方案) 什么是跨域跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,...

  • 同源策略,跨域请求处理

    跨域访问 - 跨域请求 同源策略 适用于浏览器的一种资源访问策略;同源策略(Same origin policy)...

  • 前端ajax跨域请求方案沙里淘金

    1. 所谓跨域 跨域是一种浏览器同源安全策略,也即浏览器单方面限制脚本的跨域访问。很多人可能误认为资源跨域时无法请...

  • Ajax的跨域问题

    什么是跨域及来源 跨域问题来源于浏览器的同源策略,JavaScript只能访问和操作自己域下的资源,不能访问和操作...

网友评论

    本文标题:浏览器跨域访问解决方案

    本文链接:https://www.haomeiwen.com/subject/fkeohxtx.html