js跨域

JS代码如下:

document.domain+iframe(适用于主域名雷同的图景)

在域名称叫http://server.example.com中的a.html

document.domain = 'example.com';
var $iframe = document.createElement('iframe');
$iframe.src = 'server.child.example.com/b.html';
$iframe.style.display = 'none';
document.body.appendChild($iframe);
$iframe.onload = function(){
    var doc = $iframe.contentDocument || $iframe.contentWindow.document;
    //在这里操作doc,也就是操作b.html
    $iframe.onload = null;
};

在域名叫http://server.child.example.com中的b.html

document.domain = 'example.com'

这种样式方便归方便,但也是有其便利带给的祸患

  • 安全性,当一个站点被攻击后,另三个站点会孳生安全漏洞。

  • 若页面中引进多个iframe,要想操作全体iframe,domain需求任何设置成一样的。

  可是,当进行一些相比较浓烈的前端编制程序的时候,不可制止地索要开展跨域操作,那个时候“同源计策”就显得过分苛刻。本文就那个难点,回顾了跨域所急需的有的才能。

当小编点击abc.html页面后,能够见到成效如下,从def.html重回内容了。如下:

cors

2. 由此iframe完结跨域。

  iframe跨域的主意,功效强于JSONP,它不光能用来跨域完毕HTTP乞请,还能够在前者跨域达成JavaScript调用。因而,完全分化域的跨域难点,平常使用iframe的不二秘籍来减轻。

  与JSONP本事通过创建<script>节点向区别的域提交GET乞请的干活方式相近,大家也足以透过在

  为了减轻这么些难点,大家须要在example1.com下放置叁个跨域文件,比方路线是

  当

  第几个选项是,它能够在iframe中做三个302跳转,跳转到跨域文件

  另三个取舍是,它能够在回去的页面中再松手一个iframe,指向跨域文件,同期也是将回来结果通过U奥迪Q5L编码之后作为参数缀在跨域文件UEscortL后边。

  在跨域文件中,满含黄金时代段JavaScript代码,这段代码实现的效果与利益,是从U福特ExplorerL中领取结果参数,经过一定管理后调用原本的

  依照后面包车型地铁叙说,有了跨域文件之后,大家就足以达成通过iframe情势在不一样域之间张开JavaScript调用。这些调用进程能够完全跟HTTP恳求无关,比方有个别站点能够支撑动态地调动在页面中寄放的第三方iframe的惊人,那实乃透过在第三方iframe里面检查评定自身页面的冲天变化,然后经过跨域方式的函数调用将那一个调换报告父窗口来产生的。

  既然使用iframe能够兑现跨域JavaScript调用,那么跨域提交POST必要等别的门类的HTTP乞求就不是难点。比方大家能够跨域调用目的域的JavaScript代码在目的域下提交Ajax央求(GET/POST/etc.),然后将回来的结果再跨域传原本的域。

  使用iframe跨域,优点是功用强大,扶植各类浏览器,大致能够做到别的跨域想做的政工;劣点是贯彻复杂,要管理非常多浏览器宽容难题,况且传输的数量不宜过大,过大了恐怕会当先浏览器对UWranglerL长度的限量,要考虑对数码举办分层传输等。

var win = document.getElementById("iframe").contentWindow;

document.getElementById("submit").onclick = function(e){
    e.preventDefault();
    win.postMessage(document.getElementById("message").value,"http://longen.example.com"); 
}  

window.addEventListener("message",function(e){
     e.preventDefault();
     document.getElementById("test").innerHTML = "从" + e.origin + "那里传过来的消息:n" + e.data;
},false);

jsonp

原理:
JSONP 利用
<script>成分的这些盛放药安排,网页能够收获从任何来源动态爆发的JSON数据,而这种应用方式正是所谓的
JSONP。用JSONP抓到的数据并非JSON,而是任意的JavaScript,用
JavaScript解释器运维并非用JSON分析器深入分析。

<script type="text/javascript">   
    var localHandler = function(data){
    alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);    };    
</script>   
<script type="text/javascript" src="http://remoteserver.com/remote.js"></script>

远程的remote.js

localHandler({"result":"我是远程js带来的数据"});

本人本地央浼

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>

</body>
</html>

央浼flightResult.aspx获取的数量

flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});

调用的url中传送了一个code参数,告诉服务器本身要查的是CA一九九四回航班的音信,而callback参数则告知服务器,笔者的本地回调函数叫做flightHandler,所以请把询问结果传到那几个函数中张开调用。

劣势: 援救get 安全性不高 (可以因此动态生成jsonp解决)

与ajax的区别
但ajax和jsonp其实本质上是莫衷一是的事物。ajax的骨干是由此XmlHttpRequest获取非本页内容,而jsonp的主干则是动态增添<script>标签来调用服务器提供的js脚本。

  上面我们分二种情况切磋跨域手艺:首先谈谈不一致子域的跨域手艺,然后研商完全差异乡的跨域技能。

test.php代码如下:

HTML5中的postMessage

postMessage从归于html5,可是它援助IE8+和其余浏览器,能够兑现同域传递,也能贯彻跨域传递。它总结出殡和下葬消息postMessage和选取音讯message功效。

postMessage调用语法如下

otherWindow.postMessage(message, targetOrigin, [transfer]);

  • otherWindow :
    其余窗口的二个援引,举例iframe的contentWindow属性、推行window.open重临的窗口对象、或许是命名过或数值索引的window.frames。
  • message : 就要发送到别的 window的数量,类型为string只怕object。
  • targetOrigin :
    通过窗口的origin属性来钦定哪些窗口能采用到新闻事件,其值能够是字符串”*”(表示无界定)恐怕叁个URAV4I。
  • transfer (可选卡塔尔(قطر‎ : 生机勃勃串和message 同期传递的 Transferable 对象。

接过音讯message 的习性有:

  • data :从任何 window 中传递过来的数额。
  • origin :调用 postMessage 时新闻发送方窗口的 origin 。
  • source :对发送音信的窗口对象的援引。

示范如下:域名

页面A发送音信代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>页面A</title>
</head>
<body>
    <h1>hello jsonp</h1>
    <iframe src="http://127.0.0.1/b.html" id="iframe"></iframe>
</body>
</html>
<script>
window.onload = function() {  
    var $iframe = document.getElementById('iframe');  
    var targetOrigin = "http://127.0.0.1";  
    $iframe.contentWindow.postMessage('postMessage发送消息', targetOrigin);  
}; 
</script>

页面B选择新闻代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>页面B</title>
</head>
<body>
    <h1>hello jsonp</h1>
</body>
</html>
<script>
var onmessage = function (event) {
  var data = event.data;    //消息
  var origin = event.origin; //消息来源地址
  var source = event.source; //源Window对象
  if(origin === "http://127.0.0.1:9000"){
    console.log(data, origin, source);
  }
};
// 事件兼容简单处理
if (window.addEventListener) {
  window.addEventListener('message', onmessage, false);
}
else if (window.attachEvent) {
  window.attachEvent('onmessage', onmessage);
}
else {
  window.onmessage = onmessage;
}
</script>

运维结果如下

图片 1

  JavaScript那个安全计策在张开多iframe或多窗口编程、以至Ajax编制程序时呈现越发关键。依据那一个陈设,在baidu.com下的页面中包涵的JavaScript代码,不可能访问在google.com域名下的页面内容;以致区别的子域名以内的页面也无法透过JavaScript代码相互拜候。对于Ajax的熏陶在于,通过XMLHttpRequest达成的Ajax央求,无法向不一致的域提交哀告,举例,在abc.example.com下的页面,不可能向def.example.com提交Ajax央浼,等等。

如上得以完毕形式 就可以完结ajax post跨域了。

除此以外,postMessage格局正以意料之外的速度获得种种新浏览器的支撑,应予以注重思谋。

127.0.0.1        longen.example.com

  JavaScript是风姿浪漫种在Web开拓中时时应用的前端动态脚本技巧。在JavaScript中,有八个超级重点的安全性限定,被叫做“萨姆e-Origin
Policy”(同源攻略)。这一主题对于JavaScript代码能够访问的页面内容做了相当的重视的范围,即JavaScript只好访谈与满含它的文档在同生机勃勃域下的原委。

二:使用postMessage 知识点清除 ajax中POST跨域难题。

那篇文章写得很清晰,所以转过来,格式上做了下编写制定。

以往大器晚成经在abc.example.com域下有五个abc.html页面,在longen.example.com域下有def.html页面,未来自家是期待那2个差别域名下的页面能相互通信,abc.html代码如下:

1. JSONP。

  利用在页面中创制<script>节点的艺术向区别域提交HTTP央浼的点子称为JSONP,那项本事能够化解跨域提交Ajax诉求的标题。JSONP的做事规律如下所述:

  假设在

图片 2图片 3代码

var eleScript= document.createElement(“script”);
eleScript.type = “text/javascript”;
eleScript.src = “”;
document.getElementsByTagName(“HEAD”)[0].appendChild(eleScript);

 

 

  当GET请求从

  JSONP的优点是:它不像XMLHttpRequest对象达成的Ajax央求那样受到同源战略的限制;它的包容性越来越好,在特别古老的浏览器中都能够运营,无需XMLHttpRequest或ActiveX的支撑;况且在倡议实现后方可因此调用callback的方法回传结果。

  JSONP的败笔则是:它只扶植GET央求而不接济POST等别的门类的HTTP央浼;它只帮衬跨域HTTP央求这种情形,不可能一举成功差异地的八个页面之间怎样开展JavaScript调用的主题材料。

Demo演示:

3. 接受flash完结跨域HTTP央浼

  据称,flash在浏览器中的遍布率高达70%之上。

  flash代码和JavaScript代码之间能够相互调用,而且flash的“安全沙箱”机制与JavaScript的平安机制并不尽雷同,由此,我们能够采取flash来完结跨域提交HTTP央求(扶持GET/POST等)。

  举例,大家用浏览器访谈

  这么些央浼能或不可能被成功发送,决议于在example3.com的根路线下是还是不是放置了八个crossdomain.xml以至这些crossdomain.xml的安顿如何。flash的“安全沙箱”会保险:仅当example3.com服务器在根路线下真的放置了crossdomain.xml文件同有时间在这里个文件中配备了同意选拔来自example2.com的flash的伸手时,这一个央求本领真的打响。下边是二个crossdomain.xml文件内容的例子:

<?xml version=”1.0″?>
<cross-domain-policy>
    <allow-access-from domain=”example2.com” />
</cross-domain-policy>

 

 

<form>  
      <p>  
        <label for="message" style="color:red;font-size:24px;">给iframe子窗口发一个信息:</label>  
        <input type="text" name="message" value="send" id="message" />  
        <input type="submit" value="submit" id="submit"/>  
      </p>  
</form>  
<h4>目标iframe传来的信息:</h4>  
<p id="test">暂无信息</p> 

 <iframe id="iframe"  
    src="http://longen.example.com/webSocket/def.html" style="display:none"></iframe>

(生机勃勃)差别子域的跨域技能。

  大家分三个难点来分别探讨:第多个难题是何许跨区别子域实行JavaScript调用;首个难点是哪些向区别子域提交Ajax央求。

先来消除第三个难题,借使example.com域下有七个例外子域:abc.example.com和def.example.com。现在假若在def.example.com上面有二个页面,里面定义了叁个JavaScript函数:

function funcInDef() {
   …..
}

 

 

  大家想在abc.example.com下的某部页面里调用地点的函数。再若是我们要研究的abc.example.com上边包车型大巴这几个页面是以iframe方式嵌入在def.example.com上边这叁个页面里的,那样我们大概筹划在iframe里做如下调用:

window.top.funcInDef();

 

 

  好,大家注意到,那几个调用是被眼下讲到的“同源计谋”所禁止的,JavaScript引擎会一向抛出叁个相当。

  为了促成上述调用,我们能够透过退换多个页面包车型地铁domain属性的方法成功。举例,大家得以将地点在abc.example.com和def.example.com下的八个页面的顶部都丰盛如下的JavaScript代码片段:

<script type=”text/javascript”>
    document.domain = “example.com”;
</script> 

 

 

  那样,八个页面就改成同域了,后边的调用也能够日常推行了。

  这里要求在意的一点是,四个页面包车型地铁document.domain属性只好设置成三个更顶尖的域名(除了一流域名),但不可能设置成比当下域名更加深层的子域名。举个例子,abc.example.com的页面只可以将它的domain设置成example.com,无法安装成sub.abc.example.com,当然也不可能设置成顶尖域名com。

  上边的事例谈谈的是七个页面归于iframe嵌套关系的情形,当三个页面是开拓与被展开的关系时,原理也截然雷同。

  下边大家来减轻第二个难题:怎么着向差别子域提交Ajax央求。

  经常状态下,大家会用与下部好像的代码来成立二个XMLHttpRequest对象:

图片 4图片 5代码

factories = [
    function() { return new XMLHttpRequest(); },
    function() { return new ActiveXObject(“Msxml2.XMLHTTP”); },
    function() { return new ActiveXObject(“Microsoft.XMLHTTP”); }
];
function newRequest() {
    for(var i = 0; i < factories.length; i++) {
        try{
            var factory = factories[i];
            return factory();
        } catch(e) {}
    }
    return null;

  上边的代码中援引ActiveXObject,是为着包容IE6类别浏览器。每便大家调用newRequest函数,就获得了三个恰恰创设的Ajax对象,然后用这几个Ajax对象来发送HTTP乞求。比方,下边的代码向abc.example.com发送了一个GET央求:

var request = newRequest();
request.open(“GET”, “” );
request.send(null);

 

 

  假若上边的代码包蕴在多少个abc.example.com域名下的页面里,则这几个GET哀告能够符合规律发送成功,未有别的难题。但是,假若今后要向def.example.com发送诉求,则产出跨域难题,JavaScript引擎抛出万分。

  化解的主意是,在def.example.com域下放置三个跨域文件,借使叫crossdomain.html;然后将眼下的newRequest函数的定义移到那一个跨域文件中;最终像早先修改document.domain值的做法同样,在crossdomain.html文件和abc.example.com域下调用Ajax的页面顶上部分,都抬高:

<script type=”text/javascript”>
    document.domain = “example.com”;
</script>

 

 

  为了选择跨域文件,大家在abc.example.com域下调用Ajax的页面中放到二个潜藏的指向性跨域文件的iframe,比如:

<iframe name=”xd_iframe” style=”display:none” src=”;

 

 

  此时abc.example.com域下的页面和跨域文件crossdomain.html都在同二个域(example.com)下,大家可以在abc.example.com域下的页面中去调用crossdomain.html中的newRequest函数:

var request = window.frames[“xd_iframe”].newRequest();

 

 

  那样获得的request对象,就足以向

如果今后本人在hosts文件下 ,绑定2 个域名如下:

原贴地址:http://itgeeker.com/mathml/readpaper?pid=53

<?php 
    $data=array(  
     url =>1,
      name =>'2',
      'xx-xx'=>"xx"
 );
 echo json_encode($data);
?>

(二)完全分裂域的跨域手艺。

  假如超级域名都不平等,举例example1.com和example2.com之内想通过JavaScript在前端通讯,则所急需的技巧更复杂些。

  在教授区别域的跨域技艺早先,大家先是分明一点,上面要讲的手艺也相似适用于前方跨分裂子域的情景,因为跨区别子域只是跨域难点的一个特例。当然,在合适的情况下行使合适的手艺,能够确认保证更优的频率和越来越高的安生乐业。

  简言之,依据不相同的跨域需要,跨域才能能够归为上边几类:

1、JSONP跨域GET请求
2、通过iframe完成跨域
3、flash跨域HTTP请求
4、window.postMessage

  上边详细介绍各类本事。

JS代码如下:

4. window.postMessage

  window.postMessage是HTML规范的下三个本子HTML5支撑的多少个新特征。受当前互连网手艺蒸蒸日上的影响,浏览器跨域通讯的急需越来越明朗,HTML规范终于把跨域通讯考虑进来了。但当下HTML5还是只是三个draft。

  window.postMessage是一个康宁的贯彻直接跨域通讯的形式。然则当前实际不是具有浏览器都能支撑,唯有Firefox
3、Safari 4和IE8能够援助那些调用。

选择它向别的窗口发送新闻的调用格局大致如下:

otherWindow.postMessage(message, targetOrigin);

 

 

  在收到的窗口,须要安装一个事件管理函数来选拔发过来的消息:

window.addEventListener(“message”, receiveMessage, false);
function receiveMessage(event){ 
    if (event.origin!== “”) 
        return;
}

 

 

  消息包蕴五性子格:data、origin(辅导发送窗口所在域的实在新闻)和source(代表发送窗口的handle)。

  安全性考虑:使用window.postMessage,应当要利用消息的origin和source属性来表达发送者的地位,不然会诱致XSS漏洞。

  window.postMessage在效果与利益上同iframe完毕的跨域作用相仿强大,何况利用简便,功能更加高,但劣点是它近年来在浏览器包容方面有待提升。


 

须求对初藳补充的是,在IE6,IE7下可使用IE的Opener可赋值为Object或Function的疏漏,提供postMessage方案的互补方案:

主页面:

 图片 6代码

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “;

<html xmlns=”;
<head>
    <title>CrossDomain</title>
</head>
<body>
    <iframe src=”” 
        frameborder=”0″ visible=”false” height=”0″ width=”0″ id=”ifrChild”></iframe>
    
    <script type=”text/javascript”>
        var child = document.getElementById(“ifrChild”);
        var openerObject = {
                funcInParent:function(arg){
                    alert(arg);
                    alert(‘executed by a function in parent page’);
                }
            }
            
        if(!+’v1′ && !’1′[0]){ //test browser is ie6 or ie7    
            //crack
            child.contentWindow.opener = openerObject;
        }
        else{
            //postMessage showtime
        }
        
        function onClick(){
            //debugger;
            openerObject.funcInIframe(‘data from parent page ‘);
        }
    </script>
    <input type=”button” value=”click me” onclick=”onClick()” />
</body>
</html>

用iframe内嵌其余域下的页面:

图片 7图片 8代码

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “;

<html xmlns=”;
<head>
               <script type=”text/javascript”>
                        onload = function(){
                                if(!+’v1′ && !’1′[0]){ // test browser if is ie6 or ie7
                                        window.opener.funcInIframe=function(arg){
                                                alert(arg);
                                                alert(‘executed by a function in iframe’);
                                        }
                                        window.opener.funcInParent(‘data from iframe’)
                                }
                        }
                </script>
        </head>
        <body>
        </body>
</html>

 

 

大家必要明白如下几条新闻:

 

图片 9

该方法运用2个参数,第3个参数为所发送的音信文本,但也得以是此外javascript对象,第贰个参数是接到消息的目的窗口的url地址(比如:http:127.0.0.1:8080/), 可是我们也得以在url地址字符串中使用通配符”*”,
钦定全体的域下,然而大家依然提出选择一定的域名下,otherWindow为要发送窗口对象的援用。

1.
首先,要想选择从此外的窗口发过来的新闻,就务须对窗口对象的message事件举行监听,如下代码:

def.html代码如下:

浏览器帮衬程度:IE8+,firefox4+,chrome8+  opera10+

HTML代码:

有了上边的中坚知识点,大家得以延长为达成ajax POST跨域的主题素材。

html代码和方面同样,下边是JS代码:

window.addEventListener(“message”, function(){},false);

2.
援救,供给使用window对象的postMessage方法向任何窗口发送音讯,该方法定义如下所示:

  1. 经过对window对象的message事件举办监听,可以收到新闻。
  2. 由此访谈message事件的origin属性,能够赢得新闻的发送源。
  3. 经过拜谒message事件的data属性,能够得到音信内容。
  4. 动用postMessage方法发送音讯。
  5. 通过会见message事件的source属性,能够获取音讯发送源的窗口对象(准确的说,应该是窗口的代办对象卡塔尔国。

127.0.0.1       abc.example.com

HTML5中提供了在网页文书档案之间相互摄取与发送消息的功效。使用那么些职能,只要得到到网页所在窗口对象的实例,不仅同源(域+端口号卡塔尔(قطر‎的web网页之间能够相互通讯,以至足以实现跨域通讯。

//获取跨域数据  
window.onmessage = function(e){  
     $.ajax({
          url: 'http://longen.example.com/webSocket/test.php',
          type:'POST',
          dataType:'text',
          //data: {msg:e.data},
          success: function(res) {
               var parentwin = window.parent;  
               parentwin.postMessage(res,"http://abc.example.com");//跨域发送数据  
          }
      });
 };

abc.example.com下的abc.html页面如下:

otherWindow.postMessage(message, targetOrigin);

<form>  
      <p>  
        <label for="message">给父窗口abc.html发个信息:</label>  
        <input type="text" name="message" value="send" id="message" />  
        <input type="submit" />  
      </p>  
 </form>  
 <p id="test2">暂无信息。</p>

JS代码如下:

var parentwin = window.parent; 
window.addEventListener("message",function(e){
       document.getElementById("test2").innerHTML = "从父窗口传来的域" +e.origin + ",和内容数据:" + e.data;  
       parentwin.postMessage('HI!你给我发了"'+e.data+'"。',"http://abc.example.com");
},false);

Def.html代码如下:

规律:原理也异常粗略,假若大家的域名abc.example.com下的abc.html页面须要发ajax央浼(跨域,域名称叫longen.example.com卡塔尔(قطر‎下,那么大家仍旧先跨页面文书档案的样式,和地点同样,大家得以明天longen.example.com下
创设一个页面,举例叫def.html. 那么大家未来依旧在 abc.html
页面嵌入二个隐敝域iframe
src路线指向longen.example.com域下def,html页面。进程可能和跨文书档案近似,只是以前在def.html页面中
在window.onmessage 事件内写ajax供给就可以,如下代码:

var win = document.getElementById("iframe").contentWindow;

document.getElementById("submit").onclick = function(e){
      e.preventDefault();
      win.postMessage(document.getElementById("message").value,"http://longen.example.com/"); 
}  

window.addEventListener("message",function(e){
    e.preventDefault();
    alert(typeof e.data)
    var json = JSON.parse(e.data);
     console.log(json);
    alert(json.url)
},false);

发表评论

电子邮件地址不会被公开。 必填项已用*标注