前端跨域知识总结,不正是跨域么

前者跨域知识总计

2016/11/04 · JavaScript
· 2 评论 ·
Javascript,
跨域

正文作者: 伯乐在线 –
Damonare
。未经我许可,禁止转发!
欢迎加入伯乐在线 专栏撰稿人。

  1. 什么样是跨域?
  1. 怎么样是跨域?

作者:Neal_yang

github.com/Nealyang/YOU-SHOULD-KNOW-JS/blob/master/doc/basic_js/JavaScript中的跨域计算.md

前言

深信不疑每四个前端er对于跨域那八个字都不会目生,在实际项目中使用也是比较多的。但跨域方法的应有尽有实在让人俯拾便是。老规矩,蒙受这种意况,就只可以协调总括一篇博客,作为记录。

跨域一词从字面意思看,就是跨域名嘛,但实质上跨域的界定相对不止那么狭小。具体概念如下:只要协议、域名、端口有任何1个例外,都被当做是差异的域。之所以会发出跨域那么些标题呢,其实也很不难想领会,借使随便引用外部文件,差别标签下的页面引用类似的互相的公文,浏览器很简单懵逼的,安全也得不到保证了就。什么事,都是高枕无忧第3呗。但在安全限制的同时也给注入iframe或是ajax应用上带来了诸多劳动。所以大家要通过有个别主意使本域的js能够操作别的域的页面对象大概使别的域的js能操作本域的页面对象(iframe之间)。上面是有血有肉的跨域情况详解:

跨域一词从字面意思看,就是跨域名嘛,但骨子里跨域的限制相对不止那么狭小。具体概念如下:只要协议、域名、端口有其余二个不等,都被当作是见仁见智的域。之所以会生出跨域这些难点吧,其实也很简单想通晓,假诺随便引用外部文件,区别标签下的页面引用类似的互相的文书,浏览器很不难懵逼的,安全也得不到保险了就。什么事,都是平安第①嘛。但在平安范围的同时也给注入iframe或是ajax应用上带来了诸多麻烦。所以大家要经过有个别艺术使本域的js能够操作其余域的页面对象大概使别的域的js能操作本域的页面对象(iframe之间)。上边是现实的跨域情形详解:

 

正文

UOdysseyL                           表达                    是还是不是允许通讯

UOdysseyL                          表明                    是不是允许通信

前端开发中,跨域使咱们平时遇上的二个难题,也是面试中时时被问到的局地题材,所以,这里,大家做个总括。小小意思,不足担心

1. 什么样是跨域?

跨域一词从字面意思看,就是跨域名嘛,但其实跨域的限量相对不止那么狭小。具体概念如下:只要协议、域名、端口有此外八个不比,都被作为是见仁见智的域。之所以会时有产生跨域这一个标题啊,其实也很不难想领悟,要是随便引用外部文件,不一样标签下的页面引用类似的互相的文本,浏览器很简单懵逼的,安全也得不到保证了就。什么事,都以安全第3呗。但在平安范围的还要也给注入iframe或是ajax应用上带来了不少烦劳。所以大家要因而一些措施使本域的js能够操作其余域的页面对象可能使别的域的js能操作本域的页面对象(iframe之间)。上面是实际的跨域意况详解:

JavaScript

U陆风X8L 表达 是还是不是允许通信
同一域名下 允许
同一域归属不相同文件夹 允许
同一域名,差别端口 不容许
同一域名,分歧协商 不允许
域名和域名对应ip 不允许
主域相同,子域区别不相同意(cookie那种情状下也不允许访问)
同一域名,差异二级域名(同上)
不容许(cookie那种情景下也不容许访问)
差别域名 不允许

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
URL                           说明                    是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js         同一域名下               允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js  同一域名下不同文件夹      允许
http://www.a.com:8000/a.js
http://www.a.com/b.js         同一域名,不同端口        不允许
http://www.a.com/a.js
https://www.a.com/b.js        同一域名,不同协议        不允许
http://www.a.com/a.js
http://70.32.92.74/b.js       域名和域名对应ip         不允许
http://www.a.com/a.js
http://script.a.com/b.js      主域相同,子域不同        不允许(cookie这种情况下也不允许访问)
http://www.a.com/a.js
http://a.com/b.js             同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js
http://www.a.com/b.js         不同域名                  不允许

这边大家要求留意两点:

  1. 借使是说道和端口造成的跨域难题“前台”是无法的;
  2. 在跨域难题上,域仅仅是由此“ULacrosseL的首部”来鉴定分别而不会去品尝判断一致的ip地址对应着三个域或三个域是不是在同三个ip上。
    (“U帕杰罗L的首部”指window.location.protocol
    +window.location.host,也能够驾驭为“Domains, protocols and ports
    must match”。)

 

2. 通过document.domain跨域

前边说过了,浏览器有1个同源策略,其范围之一是不能够通过ajax的法门去央浼例外源中的文书档案。
第3个限制是浏览器中不相同域的框架之间是无法拓展js的相互操作的。分化的框架之间是能够取得window对象的,但却胸中无数取得相应的习性和措施。比如,有多少个页面,它的地址是
, 在那么些页面里面有1个iframe,它的src是,
很明显,这些页面与它个中的iframe框架是区别域的,所以大家是力不从心透过在页面中书写js代码来取得iframe中的东西的:

<script type=”text/javascript”> function test(){ var iframe =
document.getElementById(‘ifame’); var win =
document.contentWindow;//能够博获得iframe里的window对象,但该window对象的性质和艺术差不离是不可用的
var doc = win.document;//那里收获不到iframe里的document对象 var name =
win.name;//那里同样得到不到window对象的name属性 } </script>
<iframe id = “iframe” src=”” onload =
“test()”></iframe>

1
2
3
4
5
6
7
8
9
<script type="text/javascript">
    function test(){
        var iframe = document.getElementById(‘ifame’);
        var win = document.contentWindow;//可以获取到iframe里的window对象,但该window对象的属性和方法几乎是不可用的
        var doc = win.document;//这里获取不到iframe里的document对象
        var name = win.name;//这里同样获取不到window对象的name属性
    }
</script>
<iframe id = "iframe" src="http://damonare.cn/b.html" onload = "test()"></iframe>

以此时候,document.domain就足以派上用场了,大家只要把和那多少个页面包车型大巴document.domain都设成相同的域名就足以了。但要注意的是,document.domain的装置是有限量的,我们不得不把document.domain设置成自己或更高超级的父域,且主域必须一律。

  • 在页面 中设置document.domain:

<iframe id = “iframe” src=”” onload =
“test()”></iframe> <script type=”text/javascript”>
document.domain = ‘damonare.cn’;//设置成主域 function test(){
alert(document.getElementById(‘iframe’).contentWindow);//contentWindow
可取得子窗口的 window 对象 } </script>

1
2
3
4
5
6
7
<iframe id = "iframe" src="http://damonare.cn/b.html" onload = "test()"></iframe>
<script type="text/javascript">
    document.domain = ‘damonare.cn’;//设置成主域
    function test(){
        alert(document.getElementById(‘iframe’).contentWindow);//contentWindow 可取得子窗口的 window 对象
    }
</script>
  • 在页面 中也设置document.domain:

<script type=”text/javascript”> document.domain =
‘damonare.cn’;//在iframe载入那个页面也安装document.domain,使之与主页面包车型大巴document.domain相同
</script>

1
2
3
<script type="text/javascript">
    document.domain = ‘damonare.cn’;//在iframe载入这个页面也设置document.domain,使之与主页面的document.domain相同
</script>

        同一域名下               允许

        同一域名下              允许

什么样是跨域

 

跨域,是指浏览器不能够实施别的网站的本子。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的四平范围。

同源策略限制了一下表现:

  • Cookie、LocalStorage 和 IndexDB 不只怕读取

  • DOM 和 JS 对象不恐怕得到

  • Ajax请求发送不出去

修改document.domain的办法只适用于不一样子域的框架间的互动。

 

3. 通过location.hash跨域

因为父窗口能够对iframe进行UXC90L读写,iframe也能够读写父窗口的U普拉多L,U奇骏L有一部分被叫作hash,正是#号及其背后的字符,它一般用来浏览器锚点定位,Server端并不关怀那部分,应该说HTTP请求进程中不会带走hash,所以那有个其他修改不会产生HTTP请求,可是会爆发浏览器历史记录。此格局的规律正是改变U路虎极光L的hash部分来开始展览双向通讯。每一个window通过改变其他window的location来发送音讯(由于七个页面不在同3个域下IE、Chrome不允许修改parent.location.hash的值,所以要依靠父窗口域名下的1个代理iframe),并通过监听自个儿的UWranglerL的变通来收纳新闻。这么些法子的通讯会招致局地不供给的浏览器历史记录,而且某些浏览器不帮助onhashchange事件,须求轮询来获知U景逸SUVL的变动,最终,那样做也存在缺点,诸如数码直接暴光在了url中,数据容积和花色都简单等。上边举例表达:

只要父页面是baidu.com/a.html,iframe嵌入的页面为google.com/b.html(此处省略了域名等url属性),要促成此几个页面间的通讯能够透过以下措施。

  • a.html传送数据到b.html
  • a.html下修改iframe的src为google.com/b.html#paco
  • b.html监听到url发生变化,触发相应操作
  •  b.html传送数据到a.html,由于五个页面不在同贰个域下IE、Chrome不允许修改parent.location.hash的值,所以要凭借父窗口域名下的3个代理iframe
    • b.html下创设一个隐形的iframe,此iframe的src是baidu.com域下的,并挂上要传递的hash数据,如src=”
    • proxy.html监听到url产生变化,修改a.html的url(因为a.html和proxy.html同域,所以proxy.html可修改a.html的url
      hash)
    • a.html监听到url发生变化,触发相应操作

b.html页面包车型客车机要代码如下:

JavaScript

try { parent.location.hash = ‘data’; } catch (e) { //
ie、chrome的安全体制不能够修改parent.location.hash, var ifrproxy =
document.createElement(‘iframe’); ifrproxy.style.display = ‘none’;
ifrproxy.src = “”;
document.body.appendChild(ifrproxy); }

1
2
3
4
5
6
7
8
9
try {  
    parent.location.hash = ‘data’;  
} catch (e) {  
    // ie、chrome的安全机制无法修改parent.location.hash,  
    var ifrproxy = document.createElement(‘iframe’);  
    ifrproxy.style.display = ‘none’;  
    ifrproxy.src = "http://www.baidu.com/proxy.html#data";  
    document.body.appendChild(ifrproxy);  
}

proxy.html页面包车型地铁严重性代码如下 :

JavaScript

//因为parent.parent(即baidu.com/a.html)和baidu.com/proxy.html属于同三个域,所以能够更改其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);

1
2
//因为parent.parent(即baidu.com/a.html)和baidu.com/proxy.html属于同一个域,所以可以改变其location.hash的值  
parent.parent.location.hash = self.location.hash.substring(1);

 同一域名下不相同文件夹      允许

  同一域名下区别文件夹      允许

 

4. 由此HTML5的postMessage方法跨域

尖端浏览器Internet Explorer 8+, chrome,Firefox , Opera 和 Safari
都将支撑那个效应。那一个效应主要总结接受音讯的”message”事件和发送音信的”postMessage”方法。比如damonare.cn域的A页面通过iframe嵌入了多个google.com域的B页面,能够经过以下办法完毕A和B的通讯

A页面通过postMessage方法发送消息:

 

JavaScript

window.onload = function() { var ifr = document.getElementById(‘ifr’);
var targetOrigin = “”;
ifr.contentWindow.postMessage(‘hello world!’, targetOrigin); };

1
2
3
4
5
window.onload = function() {  
    var ifr = document.getElementById(‘ifr’);  
    var targetOrigin = "http://www.google.com";  
    ifr.contentWindow.postMessage(‘hello world!’, targetOrigin);  
};

postMessage的接纳办法:

  • otherWindow.postMessage(message, targetOrigin);
    • otherWindow:指指标窗口,也正是给哪个window发音信,是
      window.frames 属性的积极分子要么由 window.open 方法成立的窗口
    • message: 是要发送的音讯,类型为 String、Object (IE八 、9 不辅助)
    • targetOrigin: 是限制音信接收范围,不限制请使用 ‘*

B页面通过message事件监听并收受消息:

var onmessage = function (event) { var data = event.data;//音讯 var
origin = event.origin;//新闻来源地址 var source =
event.source;//源Window对象 if(origin==”
console.log(data);//hello world! } }; if (typeof window.addEventListener
!= ‘undefined’) { window.addEventListener(‘message’, onmessage, false);
} else if (typeof window.attachEvent != ‘undefined’) { //for ie
window.attachEvent(‘onmessage’, onmessage); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var onmessage = function (event) {  
  var data = event.data;//消息  
  var origin = event.origin;//消息来源地址  
  var source = event.source;//源Window对象  
  if(origin=="http://www.baidu.com"){  
console.log(data);//hello world!  
  }  
};  
if (typeof window.addEventListener != ‘undefined’) {  
  window.addEventListener(‘message’, onmessage, false);  
} else if (typeof window.attachEvent != ‘undefined’) {  
  //for ie  
  window.attachEvent(‘onmessage’, onmessage);  
}  

同理,也得以B页面发送音讯,然后A页面监听并收受信息。

科学普及的跨域场景

 

所谓的同源是指,域名、协议、端口均为同一。

调用
非跨域

 

调用
跨域,主域差别

 

调用
跨域,子域名差异

 

调用
跨域,端口不相同

 

调用
跨域,协议分裂

 

localhost 调用 127.0.0.1 跨域

5.通过jsonp跨域

刚刚说的那三种都以双向通讯的,即多少个iframe,页面与iframe或是页面与页面之间的,下边说二种单项跨域的(一般用来获取数据),因为通过script标签引入的js是不受同源策略的界定的。所以大家能够透过script标签引入1个js或许是3个任何后缀格局(如php,jsp等)的公文,此文件重回二个js函数的调用。

诸如,有个a.html页面,它里面包车型大巴代码需求动用ajax获取1个分裂域上的json数据,固然那些json数据地址是,那么a.html中的代码就能够如此:

<script type=”text/javascript”> function dosomething(jsondata){
//处理得到的json数据 } </script> <script
src=”;

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

小编们看来获取数据的地方后边还有3个callback参数,按老规矩是用那一个参数名,可是你用别样的也同等。当然假使获取数据的jsonp地址页面不是你协调能操纵的,就得遵从提供数据的那一方的鲜明格式来操作了。

因为是当做二个js文件来引入的,所以归来的必须是2个能执行的js文件,所以那个页面包车型客车php代码或然是那般的(一定要和后端约定好哦):

PHP

<?php $callback = $_GET[‘callback’];//获得回调函数名 $data =
array(‘a’,’b’,’c’);//要赶回的多寡 echo
$callback.'(‘.json_encode($data).’)’;//输出 ?>

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

末尾,输出结果为:dosomething([‘a’,’b’,’c’]);

要是您的页面使用jquery,那么通过它包裹的格局就能很有益于的来举办jsonp操作了。

<script type=”text/javascript”>
$.getJSON(‘
//处理获得的json数据 }); </script>

1
2
3
4
5
<script type="text/javascript">
    $.getJSON(‘http://example.com/data.php?callback=?,function(jsondata)’){
        //处理获得的json数据
    });
</script>

jquery会自动生成多个大局函数来替换callback=?中的问号,之后收获到多少后又会自行销毁,实际上就是起1个一时半刻代理函数的效率。$.getJSON方法会自动判断是不是跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的款式来调用jsonp的回调函数。

  • JSONP的优缺点
    • JSONP的长处是:它不像XMLHttpRequest对象完毕的Ajax请求那样受到同源策略的限定;它的包容性更好,在进一步古老的浏览器中都可以运作,不供给XMLHttpRequest或ActiveX的支撑;并且在乞请落成后能够通过调用callback的点子回传结果。
    • JSONP的老毛病则是:它只帮衬GET请求而不匡助POST等别的类型的HTTP请求;它只帮助跨域HTTP请求那种意况,不可能解决不一致域的三个页面之间怎么进行JavaScript调用的题材。

        同一域名,分歧端口        不容许

        同一域名,分化端口        不容许

 

6. 通过CORS跨域

CO奥迪Q3S(克罗斯-Origin Resource
Sharing)跨域财富共享,定义了必须在做客跨域能源时,浏览器与服务器应该怎么样联系。CO哈弗S背后的中坚思想就是使用自定义的HTTP底部让浏览器与服务器举行调换,从而控制请求或响应是相应成功可能战败。近日,全部浏览器都帮衬该意义,IE浏览器不可能低于IE10。整个CO奥迪Q5S通信进度,都以浏览器自动达成,不需求用户参与。对于开发者来说,CO途乐S通讯与同源的AJAX通讯无差异,代码完全一致。浏览器一旦发现AJAX请求跨源,就会自动抬高级中学一年级些叠加的头消息,有时还会多出2回附加的请求,但用户不会有痛感。

由此,完成CO奇骏S通信的主要性是服务器。只要服务器完成了CO君越S接口,就可以跨源通讯。

一生的ajax请求可能是那般的:

<script type=”text/javascript”> var xhr = new XMLHttpRequest();
xhr.open(“POST”, “/damonare”,true); xhr.send(); </script>

1
2
3
4
5
<script type="text/javascript">
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "/damonare",true);
    xhr.send();
</script>

如上damonare部分是相对路径,即使大家要运用CO奥德赛S,相关Ajax代码恐怕如下所示:

<script type=”text/javascript”> var xhr = new XMLHttpRequest();
xhr.open(“GET”, “);
xhr.send(); </script>

1
2
3
4
5
<script type="text/javascript">
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://segmentfault.com/u/trigkit4/",true);
    xhr.send();
</script>

代码与前边的界别就在于相对路径换来了其余域的相对路径,约等于您要跨域访问的接口地址。

劳务器端对于COSportageS的协助,首要正是经过设置Access-Control-Allow-Origin来拓展的。借使浏览器检查和测试到对应的安装,就足以允许Ajax进行跨域的拜访。关于COTiguanS更加多明白能够看下阮一峰老师的这一篇小说:跨域财富共享
CORubiconS 详解

  • CORS和JSONP对比
    • JSONP只好促成GET请求,而CO锐界S援助具有项指标HTTP请求。
    • 运用COHavalS,开发者能够运用普通的XMLHttpRequest发起呼吁和获取数量,比起JSONP有更好的错误处理。
    • JSONP首要被老的浏览器接济,它们往往不扶助CORubiconS,而大部分现代浏览器都早就支撑了COPAJEROS)。

CORubiconS与JSONP比较,无疑越发先进、方便和可信赖。

跨域的消除办法

7. 通过window.name跨域

window对象有个name属性,该属性有特性状:即在八个窗口(window)的生命周期内,窗口载入的全数的页面都以共享一个window.name的,每种页面对window.name都有读写的权限,window.name是滴水穿石存在1个窗口载入过的富有页面中的,并不会因新页面包车型大巴载入而开始展览重置。

譬如:大家在自由三个页面输入

window.name = “My window’s name”; setTimeout(function(){
window.location.href = “”; },1000)

1
2
3
4
window.name = "My window’s name";
setTimeout(function(){
    window.location.href = "http://damonare.cn/";
},1000)

跻身damonare.cn页面后大家再检查和测试再检查和测试 window.name :

window.name; // My window’s name

1
window.name; // My window’s name

能够看看,如若在2个标签里面跳转网页的话,我们的 window.name
是不会变动的。
据书上说那么些思想,大家能够在有些页面设置好 window.name
的值,然后跳转到其它二个页面。在这些页面中就能够获得到大家正好安装的
window.name 了。

鉴于安全原因,浏览器始终会保持 window.name 是string 类型。

平等这几个法子也足以应用到和iframe的互相来:
比如:笔者的页面()中内嵌了叁个iframe:

JavaScript

<iframe id=”iframe”
src=”;

1
<iframe id="iframe" src="http://www.google.com/iframe.html"></iframe>

在 iframe.html 中装置好了 window.name 为大家要传递的字符串。
大家在 index.html 中写了下边包车型客车代码:

var iframe = document.getElementById(‘iframe’); var data = ”;
iframe.onload = function() { data = iframe.contentWindow.name; };

1
2
3
4
5
6
var iframe = document.getElementById(‘iframe’);
var data = ”;
 
iframe.onload = function() {
    data = iframe.contentWindow.name;
};

Boom!报错!肯定的,因为三个页面差异源嘛,想要搞定那几个题材得以这么干:

var iframe = document.getElementById(‘iframe’); var data = ”;
iframe.onload = function() { iframe.onload = function(){ data =
iframe.contentWindow.name; } iframe.src = ‘about:blank’; };

1
2
3
4
5
6
7
8
9
var iframe = document.getElementById(‘iframe’);
var data = ”;
 
iframe.onload = function() {
    iframe.onload = function(){
        data = iframe.contentWindow.name;
    }
    iframe.src = ‘about:blank’;
};

抑或将中间的 about:blank 替换来有些同源页面(about:blank,javascript:
和 data: 中的内容,继承了载入他们的页面包车型客车源。)

那种措施与 document.domain
方法比较,放宽了域名后缀要一如既往的范围,能够从随机页面获得 string
类型的多寡。

       同一域名,分裂协商        不允许

        同一域名,差别协商        不允许

jsonp跨域

jsonp跨域其实也是JavaScript设计情势中的一种代理格局。在html页面中通过相应的标签从不一样域名下加载静态财富文件是被浏览器允许的,所以大家能够因此那么些“犯罪漏洞”来拓展跨域。一般,大家能够动态的创造script标签,再去乞求1个带参网址来兑现跨域通讯

//原生的实现方式

let script = document.createElement(‘script’);

 

script.src = ”;

 

document.body.appendChild(script);

 

function callback(res) {

  console.log(res);

}

本来,jquery也援助jsonp的落到实处格局

$.ajax({

    url:”,

    type:’GET’,

    dataType:’jsonp’,//请求方式为jsonp

    jsonpCallback:’callback’,

    data:{

        “username”:”Nealyang”

    }

})

即便如此那种措施万分好用,不过2个最大的毛病是,只好够落到实处get请求

后记

别的诸如中间件跨域,服务器代理跨域,Flash
UTucsonLLoader跨域,动态创建script标签(简化版本的jsonp)不作切磋。

参考小说:

  • 详解js跨域难题
  • 前者消除跨域难点的8种方案(最新最全)

打赏帮衬本身写出越来越多好文章,多谢!

打赏小编

document.domain + iframe 跨域

那种跨域的主意最重庆大学的是需要主域名相同。什么是主域名相同呢?
www.nealyang.cn aaa.nealyang.cn ba.ad.nealyang.cn
这多个主域名都以nealyang.cn,而主域名不一样的就不能够用此措施。

一旦近来a.nealyang.cn 和 b.nealyang.cn 分别对应指向分化ip的服务器。

a.nealyang.cn 下有多个test.html文件

<!DOCTYPE html>

<html lang=”en”>

<head>

    <meta charset=”UTF-8″>

    <title>html</title>

    <script type=”text/javascript” src =
“jquery-1.12.1.js”></script>

</head>

<body>

    <div>A页面</div>

    <iframe

    style = “display : none”

    name = “iframe1”

    id = “iframe”

    src=””
frameborder=”0″></iframe>

    <script type=”text/javascript”>

        $(function(){

            try{

                document.domain = “nealyang.cn”

            }catch(e){}

            $(“#iframe”).load(function(){

                var jq = document.getElementById(‘iframe’).contentWindow.$

                jq.get(“

                    console.log(data);

                });

            })

        })

    </script>

</body>

</html>

选取 iframe 加载 别的域下的文件(nealyang.cn/1.html), 同时
document.domain 设置成 nealyang.cn ,当 iframe 加载完成后就足以得到nealyang.cn 域下的全局对象, 此时尝试着去乞请 nealyang.cn 域名下的
test.json (此时得以请求接口),就会发觉数目请求退步了~前端跨域知识总结,不正是跨域么。~
惊不惊喜,意正常!!!!!!!

多少请求战败,目标绝非达到,自然是还少一步:

<!DOCTYPE html>

<html lang=”en”>

<head>

    <meta charset=”UTF-8″>

    <title>html</title>

    <script type=”text/javascript” src =
“jquery-1.12.1.js”></script>

    <script type=”text/javascript”>

        $(function(){

            try{

                document.domain = “nealyang.com”

            }catch(e){}

        })

    </script>

</head>

<body>

    <div id = “div1”>B页面</div>

</body>

</html>

此刻在开展刷新浏览器,就会发现数目这一次真就是水到渠成了

打赏协理小编写出越来越多好小说,多谢!

任选一种支付办法

美高梅开户网址 1
美高梅开户网址 2

2 赞 15 收藏 2
评论

      域名和域名对应ip         不允许

      域名和域名对应ip        不允许

window.name + iframe 跨域

window.name属性可安装或然再次回到存放窗口名称的2个字符串。他的神器之处在于name值在分化页面只怕分裂域下加载后如故存在,没有改动就不会发生变化,并且能够储存非常短的name(2MB)

假定index页面请求远端服务器上的多少,我们在该页面下创设iframe标签,该iframe的src指向服务器文件的地方(iframe标签src能够跨域),服务器文件里安装好window.name的值,然后再在index.html里面读取改iframe中的window.name的值。完美~

<body>

  <script type=”text/javascript”>

    iframe = document.createElement(‘iframe’),

    iframe.src = ”;

    document.body.appendChild(iframe);

    iframe.onload = function() {

      console.log(iframe.contentWindow.name)

    };

  </script>

</body>

当然,那样依旧不够的。

因为规定借使index.html页面和和该页面里的iframe框架的src假使区别源,则也不恐怕操作框架里的其余事物,所以就取不到iframe框架的name值了,告诉您大家不是一家的,你也决不获得作者这边的数目。
既然要同源,那就换个src去指,前边说了无论如何加载window.name值都不会转移,于是大家在index.html相同目录下,新建了个proxy.html的空页面,修改代码如下:

<body>

  <script type=”text/javascript”>

    iframe = document.createElement(‘iframe’),

    iframe.src = ”;

    document.body.appendChild(iframe);

    iframe.onload = function() {

      iframe.src = ”;

      console.log(iframe.contentWindow.name)

    };

  </script>

</body>

非凡就像绝对美丽好,在iframe载入进度中,飞快重置iframe.src的针对性,使之与index.html同源,那么index页面就能去获取它的name值了!不过现实是残暴的,iframe在切切实实中的表现是平昔不停地刷新,
也很好通晓,每一遍触发onload时间后,重置src,相当于重新载入页面,又触发onload事件,于是就不停地刷新了(可是供给的多少仍是可以出口的)。修改后代码如下:

<body>

  <script type=”text/javascript”>

    iframe = document.createElement(‘iframe’);

    iframe.style.display = ‘none’;

    var state = 0;

 

    iframe.onload = function() {

      if(state === 1) {

          var data = JSON.parse(iframe.contentWindow.name);

          console.log(data);

          iframe.contentWindow.document.write(”);

          iframe.contentWindow.close();

        document.body.removeChild(iframe);

      } else if(state === 0) {

          state = 1;

          iframe.contentWindow.location = ”;

      }

    };

 

    iframe.src = ”;

    document.body.appendChild(iframe);

  </script>

</body>

据此如上,大家就得到了服务器重临的数额,但是有多少个尺码是必不可少的:

  • iframe标签的跨域能力

  • window.names属性值在文书档案刷新后照旧留存的力量

关于小编:Damonare

美高梅开户网址 3

今日头条专栏[前端进击者]

个人主页 ·
小编的小说 ·
19 ·
         

美高梅开户网址 4

location.hash + iframe 跨域

此跨域方法和上边介绍的可比接近,一样是动态插入三个iframe然后安装其src为服务端地址,而服务端同样输出一端js代码,也还要通过与子窗口之间的通讯来成功多少的传输。

关于锚点相信大家都已经精通了,其实正是安装锚点,让文档钦命的附和的地点。锚点的安装用a标签,然后href指向要跳转到的id,当然,前提是您得有个滚动条,不然也糟糕滚动嘛是啊。

而location.hash其实就是url的锚点。比如

基础知识补充完结,下边大家来说下如何落到实处跨域

假如index页面要收获远端服务器的数码,动态的插入一个iframe,将iframe的src执行服务器的地方,那时候的top
window
和包裹这几个iframe的子窗口是不可能通讯的,因为同源策略,所以改变子窗口的门路就足以了,将数据作为改变后的门道的hash值加载路径上,然后就足以通讯了。将数据加在index页面地址的hash上,
index页面监听hash的变更,h5的hashchange方法

<body>

  <script type=”text/javascript”>

    function getData(url, fn) {

      var iframe = document.createElement(‘iframe’);

      iframe.style.display = ‘none’;

      iframe.src = url;

 

      iframe.onload = function() {

        fn(iframe.contentWindow.location.hash.substring(1));

        window.location.hash = ”;

        document.body.removeChild(iframe);

      };

 

      document.body.appendChild(iframe);

    }

 

    // get data from server

    var url = ”;

    getData(url, function(data) {

      var jsondata = JSON.parse(data);

      console.log(jsondata.name + ‘ ‘ + jsondata.age);

    });

  </script>

</body>

增加补充表达:其实location.hash和window.name都以大半的,都以应用全局对象属性的章程,然后那二种办法和jsonp也是千篇一律的,正是只可以够完结get请求

     主域相同,子域分裂      
 不一样意(cookie那种境况下也不一致意访问)

      主域相同,子域不一样       
不允许(cookie这种气象下也不允许访问)

postMessage跨域

那是由H5提议来的3个炫酷的API,IE8+,chrome,ff都早就支撑促成了那个作用。那几个效率也是特其他简易,在这之中囊括接受信息的Message时间,和发送音信的postMessage方法。

发送消息的postMessage方法是向外界窗口发送消息

otherWindow.postMessage(message,targetOrigin);

otherWindow指的是目的窗口,也正是要给哪三个window发送新闻,是window.frames属性的分子要么是window.open方法成立的窗口。
Message是要发送的音信,类型为String,Object(IE八 、9不支持Obj),targetOrigin是限量音讯接受范围,不限定就用星号
*

收受音讯的message事件

var onmessage = function(event) {

  var data = event.data;

  var origin = event.origin;

}

 

if(typeof window.addEventListener != ‘undefined’){

    window.addEventListener(‘message’,onmessage,false);

}else if(typeof window.attachEvent != ‘undefined’){

    window.attachEvent(‘onmessage’, onmessage);

}

举个栗子

a.html()

<iframe id=”iframe” src=”” style=”display:none;”></iframe>

<script>

    var iframe = document.getElementById(‘iframe’);

    iframe.onload = function() {

        var data = {

            name: ‘aym’

        };

        // 向neal传送跨域数据

        iframe.contentWindow.postMessage(JSON.stringify(data), ”);

    };

 

    // 接受domain2重回数据

    window.addEventListener(‘message’, function(e) {

        alert(‘data from neal —> ‘ + e.data);

    }, false);

</script>

b.html()

<script>

    // 接收domain1的数据

    window.addEventListener(‘message’, function(e) {

        alert(‘data from nealyang —> ‘ + e.data);

 

        var data = JSON.parse(e.data);

        if (data) {

            data.number = 16;

 

            // 处理后再发回nealyang

            window.parent.postMessage(JSON.stringify(data), ”);

        }

    }, false);

</script>

跨域能源共享 COSportageS

因为是近日主流的跨域化解方案。所以那里多介绍点。

            同一域名,不一样二级域名(同上)
差别意(cookie那种情景下也不允许访问)

            同一域名,不一致二级域名(同上)
不容许(cookie那种情状下也不容许访问)

简介

COCR-VS是一个W3C标准,全称是”跨域能源共享”(克罗丝-origin resource
sharing)。
它同意浏览器向跨源服务器,发出XMLHttpRequest请求,从而克制了AJAX只可以同源使用的限量。

COLANDS须求浏览器和服务器同时补助。方今,全部浏览器都帮衬该意义,IE浏览器不能够低于IE10。IE8+:IE8/9亟需采取XDomainRequest对象来帮助COSportageS。

整套COTucsonS通讯进度,都是浏览器自动达成,不须求用户参加。对于开发者来说,COCR-VS通讯与同源的AJAX通讯一点差别也没有,代码完全一样。浏览器一旦发觉AJAX请求跨源,就会自动抬高级中学一年级些附加的头音信,有时还会多出一回附加的伸手,但用户不会有感觉。
因而,完成CO奥迪Q5S通讯的关键是服务器。只要服务器达成了CO酷威S接口,就能够跨源通讯。

两种请求

说起来很搞笑,分为两种请求,一种是简不难单请求,另一种是非不难请求。只要满意下边条件就是简特邀求

  • 伸手格局为HEAD、POST 也许 GET

  • http头消息不超过一下字段:Accept、Accept-Language 、
    Content-Language、 Last-伊芙nt-ID、
    Content-Type(限于四个值:application/x-www-form-urlencoded、multipart/form-data、text/plain)

缘何要分成简单请求和非简单请求,因为浏览器对那三种请求格局的处理情势是见仁见智的。

        区别域名                  不容许

        不一样域名                  不容许

总结请求

那边大家要求小心两点:

此间大家须求注意两点:

大旨流程

对于简易请求,浏览器直接发生CORAV4S请求。具体来说,正是在头新闻之中,扩张三个Origin字段。
下边是叁个例证,浏览器发现此次跨源AJAX请求是简单请求,就机关在头新闻之中,添加三个Origin字段。

GET /cors HTTP/1.1

Origin: 

Host: api.alice.com

Accept-Language: en-US

Connection: keep-alive

User-Agent: Mozilla/5.0

Origin字段用来表达,此次请求来自哪个源(协议 + 域名 +
端口)。服务器依据那几个值,决定是还是不是允许本次请求。

一旦Origin钦命的源,不在许可范围内,服务器会回来多个健康的HTTP回应。
浏览器发现,这么些回答的头消息并未包括Access-Control-Allow-Origin字段(详见下文),就通晓出错了,从而抛出3个错误,被XMLHttpRequest的onerror回调函数捕获。

注意,那种不当不能透过情景码识别,因为HTTP回应的状态码有恐怕是200。

假设Origin钦命的域名在批准范围内,服务器再次回到的响应,会多出多少个头音信字段。

Access-Control-Allow-Origin: 

   Access-Control-Allow-Credentials: true

   Access-Control-Expose-Headers: FooBar

   Content-Type: text/html; charset=utf-8

下面的头音讯之中,有八个与COLX570S请求相关的字段,都是Access-Control-起先

  • Access-Control-Allow-Origin
    :该字段是必须的。它的值要么是伸手时Origin字段的值,要么是一个*,表示接受任意域名的央浼

  • Access-Control-Allow-Credentials:
    该字段可选。它的值是二个布尔值,表示是或不是同意发送Cookie。默许情状下,Cookie不包蕴在COPAJEROS请求之中。设为true,即意味着服务器显著准予,库克ie能够分包在呼吁中,一起发给服务器。那几个值也不得不设为true,借使服务器不要浏览器发送Cookie,删除该字段即可。

  • Access-Control-Expose-Headers:该字段可选。CO智跑S请求时,XMLHttpRequest对象的getResponseHeader()方法只可以获得陆个主题字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。倘使想得到其它字段,就必须在Access-Control-Expose-Headers里面钦定。

假定是说道和端口造成的跨域难点“前台”是不能够的;

比方是切磋和端口造成的跨域难题“前台”是无力回天的;

 

在跨域难点上,域仅仅是透过“U智跑L的首部”来甄别而不会去尝尝判断一致的ip地址对应着多少个域或多少个域是或不是在同贰个ip上。

在跨域难题上,域仅仅是经过“U途达L的首部”来鉴定区别而不会去尝试判断一致的ip地址对应着七个域或四个域是或不是在同3个ip上。

withCredentials 属性

上边说到,COPRADOS请求默许不发送Cookie和HTTP认证音讯。假使要把Cookie发到服务器,一方面要服务器同意,钦命Access-Control-Allow-Credentials字段。

一边,开发者必须在AJAX请求中打开withCredentials属性。

var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容

 

// 前端安装是或不是带cookie

xhr.withCredentials = true;

 

xhr.open(‘post’, ”, true);

xhr.setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’);

xhr.send(‘user=admin’);

 

xhr.onreadystatechange = function() {

    if (xhr.readyState == 4 && xhr.status == 200) {

        alert(xhr.responseText);

    }

};

 

// jquery

$.ajax({

    …

   xhrFields: {

       withCredentials: true // 前端安装是不是带cookie

   },

   crossDomain: true, //
会让请求头中涵盖跨域的额外新闻,但不会含cookie

    …

});

不然,即便服务器同意发送Cookie,浏览器也不会发送。可能,服务器要求安装Cookie,浏览器也不会处理。
但是,假诺省略withCredentials设置,有的浏览器还是会共同发送Cookie。那时,能够显式关闭withCredentials。

亟需留意的是,假诺要发送Cookie,Access-Control-Allow-Origin就不能够设为星号,必须内定明显的、与请求网页一致的域名。同时,Cookie依旧遵照同源政策,唯有用劳动器域名设置的Cookie才会上传,其余域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也不知所可读取服务器域名下的Cookie。

(“U奥迪Q5L的首部”指window.location.protocol
+window.location.host,也能够掌握为“Domains, protocols and ports must
match”。)

(“UMuranoL的首部”指window.location.protocol
+window.location.host,也得以知道为“Domains, protocols and ports must
match”。)

非简单请求

非简单请求是那种对服务器有特殊须要的哀告,比如请求方法是PUT或DELETE,恐怕Content-Type字段的项目是application/json。

非不难请求的CO奥迪Q5S请求,会在正儿八经通信从前,扩展3次HTTP查询请求,称为”预检”请求(preflight)。

浏览器先明白服务器,当前网页所在的域名是还是不是在服务器的许可名单之中,以及能够行使什么HTTP动词和头消息字段。唯有得到肯定答复,浏览器才会时有爆发正式的XMLHttpRequest请求,不然就报错。

var url = ”;

var xhr = new XMLHttpRequest();

xhr.open(‘PUT’, url, true);

xhr.setRequestHeader(‘X-Custom-Header’, ‘value’);

xhr.send();

浏览器发现,那是1个非不难请求,就自动发出一个”预检”请求,供给服务器确认能够那样请求。上面是其一”预检”请求的HTTP头音讯。

OPTIONS /cors HTTP/1.1

   Origin: 

   Access-Control-Request-Method: PUT

   Access-Control-Request-Headers: X-Custom-Header

   Host: api.alice.com

   Accept-Language: en-US

   Connection: keep-alive

   User-Agent: Mozilla/5.0…

“预检”请求用的央浼方法是OPTIONS,表示这一个请求是用来理解的。头音信里面,关键字段是Origin,表示请求来自哪个源。

除外Origin字段,”预检”请求的头消息蕴含八个例外字段。

  • Access-Control-Request-Method:该字段是必须的,用来列出浏览器的CO卡宴S请求会用到什么HTTP方法,上例是PUT。

  • Access-Control-Request-Headers:该字段是3个逗号分隔的字符串,钦命浏览器COXC90S请求会额外发送的头消息字段,上例是X-Custom-Header

  1. 通过document.domain跨域
  1. 通过document.domain跨域
 

近来说过了,浏览器有三个同源策略,其范围之一是不可能因而ajax的法子去伏乞例外源中的文书档案。
第①个限制是浏览器中不一致域的框架之间是不能够展开js的互相操作的。不一样的框架之间是足以博得window对象的,但却一筹莫展获得相应的天性和艺术。比如,有2个页面,它的地点是
, 在那一个页面里面有三个iframe,它的src是,
很明朗,那一个页面与它里面包车型地铁iframe框架是分裂域的,所以咱们是无能为力通过在页面中书写js代码来收获iframe中的东西的:

后边说过了,浏览器有一个同源策略,其范围之一是不能够经过ajax的法子去央浼例外源中的文书档案。
第二个限制是浏览器中分化域的框架之间是不能够拓展js的交互操作的。差异的框架之间是足以得到window对象的,但却无计可施赢得相应的品质和章程。比如,有2个页面,它的地点是
, 在那一个页面里面有三个iframe,它的src是,
很分明,这么些页面与它个中的iframe框架是差异域的,所以大家是心有余而力不足透过在页面中书写js代码来取得iframe中的东西的:

预检请求的回应

服务器收到”预检”请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段未来,确认允许跨源请求,就足以做出回应

HTTP/1.1 200 OK

Date: Mon, 01 Dec 2008 01:15:39 GMT

Server: Apache/2.0.61 (Unix)

Access-Control-Allow-Origin: 

Access-Control-Allow-Methods: GET, POST, PUT

Access-Control-Allow-Headers: X-Custom-Header

Content-Type: text/html; charset=utf-8

Content-Encoding: gzip

Content-Length: 0

Keep-Alive: timeout=2, max=100

Connection: Keep-Alive

Content-Type: text/plain

地方的HTTP回应中,关键的是Access-Control-Allow-Origin字段,表示

要是浏览器否定了”预检”请求,会回到二个健康的HTTP回应,可是没有其余CO哈弗S相关的头新闻字段。那时,浏览器就会确认,服务器差别意预检请求,由此触发2个错误,被XMLHttpRequest对象的onerror回调函数捕获。控制台会打字与印刷出如下的报错音信。

服务器回应的此外CO宝马7系S相关字段如下:

Access-Control-Allow-Methods: GET, POST, PUT

Access-Control-Allow-Headers: X-Custom-Header

Access-Control-Allow-Credentials: true

Access-Control-Max-Age: 1728000

 

  • Access-Control-Allow-Methods:该字段必需,它的值是逗号分隔的二个字符串,注解服务器援助的享有跨域请求的格局。注意,再次来到的是全部协助的方法,而不单是浏览器请求的尤其格局。那是为着制止频仍”预检”请求。

  • Access-Control-Allow-Headers:假诺浏览器请求包蕴Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是须求的。它也是1个逗号分隔的字符串,评释服务器支持的保有头消息字段,不压制浏览器在”预检”中呼吁的字段。

  • Access-Control-Allow-Credentials: 该字段与简便请求时的意义相同。

  • Access-Control-马克斯-Age:
    该字段可选,用来内定这次预检请求的有效期,单位为秒。上边结果中,有效期是20天(172柒仟秒),即允许缓存该条回应172柒仟秒(即20天),在此时期,不用发出另一条预检请求。

   function test(){

    function test(){

 

       var iframe = document.getElementById(‘ifame’);

        var iframe = document.getElementById(‘ifame’);

浏览器常常请求应对

假如服务器通过了”预检”请求,以后每便浏览器日常的COMuranoS请求,就都跟简单请求一样,会有二个Origin头音信字段。服务器的对答,也都会有三个Access-Control-Allow-Origin头音讯字段。

PUT /cors HTTP/1.1

Origin: 

Host: api.alice.com

X-Custom-Header: value

Accept-Language: en-US

Connection: keep-alive

User-Agent: Mozilla/5.0…

浏览器的正规CORS请求。上边头新闻的Origin字段是浏览器自动抬高的。上面是服务器常规的作答。

Access-Control-Allow-Origin: 

Content-Type: text/html; charset=utf-8

Access-Control-Allow-Origin字段是每趟回应都必将包蕴的

       var win =
document.contentWindow;//能够得到到iframe里的window对象,但该window对象的质量和格局大概是不可用的

        var win =
document.contentWindow;//能够收获到iframe里的window对象,但该window对象的品质和艺术大致是不可用的

结束语

CO汉兰达S与JSONP的施用指标相同,可是比JSONP更强大。JSONP只帮衬GET请求,CO福睿斯S扶助具有品类的HTTP请求。JSONP的优势在于匡助老式浏览器,以及能够向不协理CO奥迪Q5S的网站呼吁数据。

       var doc = win.document;//那里获得不到iframe里的document对象

        var doc = win.document;//那里得到不到iframe里的document对象

WebSocket合计跨域

WebSocket
protocol是HTML5一种新的商谈。它完毕了浏览器与服务器全双工通讯,同时同意跨域通信,是server
push技术的一种很好的贯彻。

原生WebSocket
API使用起来不太有利,大家使用Socket.io,它很好地卷入了webSocket接口,提供了更简短、灵活的接口,也对不帮忙webSocket的浏览器提供了向下包容。

前者代码:

<div>user input:<input type=”text”></div>

<script src=”./socket.io.js”></script>

<script>

var socket = io(”);

 

// 连接成功拍卖

socket.on(‘connect’, function() {

    // 监听服务端音讯

    socket.on(‘message’, function(msg) {

        console.log(‘data from server: —> ‘ + msg);

    });

 

    // 监听服务端关闭

    socket.on(‘disconnect’, function() {

        console.log(‘Server socket has closed.’);

    });

});

 

document.getElementsByTagName(‘input’)[0].onblur = function() {

    socket.send(this.value);

};

</script>

node Server

var http = require(‘http’);

var socket = require(‘socket.io’);

美高梅开户网址, 

// 启http服务

var server = http.createServer(function(req, res) {

    res.writeHead(200, {

        ‘Content-type’: ‘text/html’

    });

    res.end();

});

 

server.listen(‘8080’);

console.log(‘Server is running at port 8080…’);

 

// 监听socket连接

socket.listen(server).on(‘connection’, function(client) {

    // 接收新闻

    client.on(‘message’, function(msg) {

        client.send(‘hello:’ + msg);

        console.log(‘data from client: —> ‘ + msg);

    });

 

    // 断开处理

    client.on(‘disconnect’, function() {

        console.log(‘Client socket has closed.’);

    });

});

       var name = win.name;//那里同样得到不到window对象的name属性

        var name = win.name;//那里同样取得不到window对象的name属性

node代理跨域

node中间件达成跨域代理,是透过启八个代理服务器,达成多少的转账,也得以由此安装cookieDomainRewrite参数修改响应头中cookie中域名,完毕当前域的cookie写入,方便接口登录认证。

使用node + express + http-proxy-middleware搭建一个proxy服务器

前者代码

var xhr = new XMLHttpRequest();

 

// 前端开关:浏览器是不是读写cookie

xhr.withCredentials = true;

 

// 访问http-proxy-middleware代理服务器

xhr.open(‘get’, ”, true);

xhr.send();

后端代码

var express = require(‘express’);

var proxy = require(‘http-proxy-middleware’);

var app = express();

 

app.use(‘/’, proxy({

    // 代理跨域指标接口

    target: ”,

    changeOrigin: true,

 

    // 修改响应头音信,实现跨域并同意带cookie

    onProxyRes: function(proxyRes, req, res) {

        res.header(‘Access-Control-Allow-Origin’, ”);

        res.header(‘Access-Control-Allow-Credentials’, ‘true’);

    },

 

    // 修改响应消息中的cookie域名

    cookieDomainRewrite: ‘www.domain1.com’ // 能够为false,表示不修改

}));

 

app.listen(3000);

console.log(‘Proxy server is listen at port 3000…’);

   }

    }

nginx代理跨域

NGINX其实个人尚未怎么玩过,所以一时也就无法误人子弟了,原谅俺才疏尚浅~
有空子学习研究再回到补充~~

其一时半刻候,document.domain就能够派上用场了,大家要是把

那一个时候,document.domain就足以派上用场了,大家只要把

参照文书档案

 

在页面 中设置document.domain:

在页面 中设置

   document.domain = ‘damonare.cn’;//设置成主域

document.domain:

   function test(){

    document.domain = ‘damonare.cn’;//设置成主域

     
 alert(document.getElementById(‘iframe’).contentWindow);//contentWindow
可取得子窗口的 window 对象

    function test(){

   }

       
alert(document.getElementById(‘iframe’).contentWindow);//contentWindow
可取得子窗口的 window 对象

在页面 中也安装document.domain:

    }

   document.domain =
‘damonare.cn’;//在iframe载入那些页面也设置document.domain,使之与主页面包车型客车document.domain相同

在页面 中也安装document.domain:

修改document.domain的方式只适用于差别子域的框架间的互相。

    document.domain =
‘damonare.cn’;//在iframe载入那几个页面也安装document.domain,使之与主页面包车型地铁document.domain相同

  1. 通过location.hash跨域

修改document.domain的章程只适用于差异子域的框架间的互相。

因为父窗口能够对iframe进行URL读写,iframe也能够读写父窗口的U奥德赛L,U奇骏L有部分被号称hash,便是#号及其背后的字符,它一般用来浏览器锚点定位,Server端并不关怀这部分,应该说HTTP请求进度中不会带走hash,所以那有些的改动不会生出HTTP请求,可是会时有产生浏览器历史记录。此措施的法则正是改变ULacrosseL的hash部分来进行双向通讯。种种window通过改变其他window的location来发送音讯(由于七个页面不在同二个域下IE、Chrome不容许修改parent.location.hash的值,所以要借助父窗口域名下的一个代理iframe),并由此监听本人的U帕杰罗L的生成来接收新闻。这些主意的通讯会招致局地不须求的浏览器历史记录,而且有个别浏览器不协助onhashchange事件,要求轮询来获知URubiconL的更改,最终,那样做也设有缺点,诸如数码直接暴光在了url中,数据体积和品种都不难等。上边举例表达:

  1. 通过location.hash跨域

比方父页面是baidu.com/a.html,iframe嵌入的页面为google.com/b.html(此处省略了域名等url属性),要落到实处此四个页面间的通讯能够经过以下办法。

因为父窗口能够对iframe进行UPAJEROL读写,iframe也能够读写父窗口的U中华VL,UEscortL有一对被誉为hash,正是#号及其背后的字符,它一般用来浏览器锚点定位,Server端并不爱抚那某个,应该说HTTP请求进度中不会带领hash,所以这一部分的改动不会产生HTTP请求,不过会发出浏览器历史记录。此方法的规律正是改变U揽胜极光L的hash部分来展开双向通讯。种种window通过改动其余window的location来发送消息(由于多个页面不在同2个域下IE、Chrome分化意修改parent.location.hash的值,所以要重视父窗口域名下的二个代理iframe),并经过监听自身的UOdysseyL的转移来收纳新闻。那几个办法的通讯会造成一些不必要的浏览器历史记录,而且某些浏览器不扶助onhashchange事件,须求轮询来获知UHavalL的转移,最后,这样做也设有欠缺,诸如数码直接暴光在了url中,数据体积和种类都有限等。下边举例表明:

a.html传送数据到b.html

只要父页面是baidu.com/a.html,iframe嵌入的页面为google.com/b.html(此处省略了域名等url属性),要贯彻此四个页面间的通讯能够经过以下办法。

a.html下修改iframe的src为google.com/b.html#paco

a.html传送数据到b.html

b.html监听到url产生变化,触发相应操作

a.html下修改iframe的src为google.com/b.html#paco

b.html传送数据到a.html,由于八个页面不在同1个域下IE、Chrome不容许修改parent.location.hash的值,所以要信赖父窗口域名下的一个代理iframe

b.html监听到url发生变化,触发相应操作

b.html下创办二个潜伏的iframe,此iframe的src是baidu.com域下的,并挂上要传送的hash数据,如src=”

b.html传送数据到a.html,由于七个页面不在同1个域下IE、Chrome不容许修改parent.location.hash的值,所以要凭借父窗口域名下的3个代理iframe

proxy.html监听到url爆发变化,修改a.html的url(因为a.html和proxy.html同域,所以proxy.html可修改a.html的url
hash)

b.html下创办一个东躲河南的iframe,此iframe的src是baidu.com域下的,并挂上要传送的hash数据,如src=”

a.html监听到url产生变化,触发相应操作

proxy.html监听到url产生变化,修改a.html的url(因为a.html和proxy.html同域,所以proxy.html可修改a.html的url
hash)

b.html页面包车型大巴机要代码如下:

a.html监听到url产生变化,触发相应操作

try {

b.html页面包车型大巴首要性代码如下:

parent.location.hash = ‘data’;

try {

} catch (e) {

parent.location.hash = ‘data’;

// ie、chrome的安全机制不能修改parent.location.hash,

} catch (e) {

var ifrproxy = document.createElement(‘iframe’);

// ie、chrome的安全部制不能修改parent.location.hash,

ifrproxy.style.display = ‘none’;

var ifrproxy = document.createElement(‘iframe’);

ifrproxy.src = “”;

ifrproxy.style.display = ‘none’;

document.body.appendChild(ifrproxy);

ifrproxy.src = “”;

}

document.body.appendChild(ifrproxy);

proxy.html页面包车型大巴首要代码如下 :

}

//因为parent.parent(即baidu.com/a.html)和baidu.com/proxy.html属于同2个域,所以能够转移其location.hash的值

proxy.html页面包车型地铁重庆大学代码如下 :

parent.parent.location.hash = self.location.hash.substring(1);

//因为parent.parent(即baidu.com/a.html)和baidu.com/proxy.html属于同四个域,所以能够更改其location.hash的值

  1. 通过HTML5的postMessage方法跨域

parent.parent.location.hash = self.location.hash.substring(1);

高级浏览器Internet Explorer 8+, chrome,Firefox , Opera 和 Safari
都将支持这么些功用。这一个功用主要包罗接受音讯的”message”事件和殡葬音信的”postMessage”方法。比如damonare.cn域的A页面通过iframe嵌入了1个google.com域的B页面,能够透过以下措施完成A和B的通信

  1. 经过HTML5的postMessage方法跨域

A页面通过postMessage方法发送信息:

高等浏览器Internet Explorer 8+, chrome,Firefox , Opera 和 Safari
都将支撑这几个功能。这一个效果首要蕴涵接受音信的”message”事件和发送消息的”postMessage”方法。比如damonare.cn域的A页面通过iframe嵌入了七个google.com域的B页面,能够透过以下形式完成A和B的通讯

window.onload = function() {

A页面通过postMessage方法发送新闻:

var ifr = document.getElementById(‘ifr’);

window.onload = function() {

var targetOrigin = “”;  

var ifr = document.getElementById(‘ifr’);

ifr.contentWindow.postMessage(‘hello world!’, targetOrigin);

var targetOrigin = “”;

};

ifr.contentWindow.postMessage(‘hello world!’, targetOrigin);

postMessage的应用方式:

};

otherWindow.postMessage(message, targetOrigin);

postMessage的选择办法:

otherWindow:指指标窗口,相当于给哪些window发音讯,是 window.frames
属性的积极分子要么由 window.open 方法创制的窗口

otherWindow.postMessage(message, targetOrigin);

message: 是要发送的音讯,类型为 String、Object (IE⑧ 、9 不协理)

otherWindow:指目标窗口,也正是给哪些window发音信,是 window.frames
属性的积极分子要么由 window.open 方法创制的窗口

targetOrigin: 是限制新闻接收范围,不限量请使用 ‘*

message: 是要发送的新闻,类型为 String、Object (IE八 、9 不补助)

B页面通过message事件监听并接受新闻:

targetOrigin: 是限制新闻接收范围,不限定请使用 ‘*

var onmessage = function (event) {

B页面通过message事件监听并接受音信:

var data = event.data;//消息

var onmessage = function (event) {

var origin = event.origin;//新闻来源地址

var data = event.data;//消息

var source = event.source;//源Window对象

var origin = event.origin;//新闻来源地址

if(origin==”

var source = event.source;//源Window对象

console.log(data);//hello world!

if(origin==”

}

console.log(data);//hello world!

};

}

if (typeof window.addEventListener != ‘undefined’) {

};

window.addEventListener(‘message’, onmessage, false);

if (typeof window.addEventListener != ‘undefined’) {

} else if (typeof window.attachEvent != ‘undefined’) {

window.addEventListener(‘message’, onmessage, false);

//for ie

} else if (typeof window.attachEvent != ‘undefined’) {

window.attachEvent(‘onmessage’, onmessage);

//for ie

}

window.attachEvent(‘onmessage’, onmessage);

同理,也得以B页面发送消息,然后A页面监听并接受信息。

}

5.通过jsonp跨域

同理,也得以B页面发送消息,然后A页面监听并收受新闻。

刚刚说的这两种都以双向通讯的,即多少个iframe,页面与iframe或是页面与页面之间的,下边说两种单项跨域的(一般用来获取数据),因为通过script标签引入的js是不受同源策略的限定的。所以大家得以经过script标签引入四个js大概是3个别样后缀形式(如php,jsp等)的公文,此文件再次回到多个js函数的调用。

5.通过jsonp跨域

例如,有个a.html页面,它在那之中的代码必要选拔ajax获取二个区别域上的json数据,借使这一个json数据地址是

刚刚说的那二种都以双向通讯的,即八个iframe,页面与iframe或是页面与页面之间的,下边说三种单项跨域的(一般用来获取数据),因为通过script标签引入的js是不受同源策略的限量的。所以大家能够因此script标签引入三个js或许是二个其他后缀方式(如php,jsp等)的文书,此文件重回一个js函数的调用。

function dosomething(jsondata){

例如,有个a.html页面,它里面包车型地铁代码供给利用ajax获取三个分歧域上的json数据,假诺这一个json数据地址是

//处理得到的json数据

function dosomething(jsondata){

}

//处理得到的json数据

我们见到获取数据的地方后边还有四个callback参数,按规矩是用那几个参数名,但是你用别的的也同样。当然假诺获取数据的jsonp地址页面不是你协调能决定的,就得服从提供数据的那一方的鲜明格式来操作了。

}

因为是当做二个js文件来引入的,所以):

大家看出获取数据的地点后边还有三个callback参数,按常规是用这几个参数名,然则你用其余的也如出一辙。当然假如获取数据的jsonp地址页面不是您自身能控制的,就得根据提供数据的那一方的显明格式来操作了。

$callback = $_GET[‘callback’];//得到回调函数名

因为是当做三个js文件来引入的,所以):

$data = array(‘a’,’b’,’c’);//要回来的多少

$callback = $_GET[‘callback’];//得到回调函数名

echo $callback.'(‘.json_encode($data).’)’;//输出

$data = array(‘a’,’b’,’c’);//要回来的数码

?>

echo $callback.'(‘.json_encode($data).’)’;//输出

最后,输出结果为:dosomething([‘a’,’b’,’c’]);

?>

万一您的页面使用jquery,那么通过它包裹的法门就能很方便的来展开jsonp操作了。

最后,输出结果为:dosomething([‘a’,’b’,’c’]);

$.getJSON(‘

假设你的页面使用jquery,那么通过它包裹的法子就能很便宜的来进行jsonp操作了。

//处理获得的json数据

$.getJSON(‘

});

//处理获得的json数据

jquery会自动生成3个大局函数来替换callback=?中的问号,之后收获到多少后又会自行销毁,实际上就是起1个目前期理函数的意义。$.getJSON方法会自动判断是还是不是跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的款型来调用jsonp的回调函数。

});

JSONP的优缺点

jquery会自动生成一个大局函数来替换callback=?中的问号,之后收获到多少后又会自动销毁,实际上正是起三个权且代理函数的作用。$.getJSON方法会自动判断是或不是跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的情势来调用jsonp的回调函数。

JSONP的长处是:它不像XMLHttpRequest对象落成的Ajax请求那样受到同源策略的范围;它的兼容性更好,在更为古老的浏览器中都能够运维,不要求XMLHttpRequest或ActiveX的支撑;并且在伏乞完结后得以透过调用callback的法门回传结果。

JSONP的利害

JSONP的败笔则是:它只协理GET请求而不协理POST等另外门类的HTTP请求;它只补助跨域HTTP请求那种景色,不能够缓解分化域的多个页面之间什么开始展览JavaScript调用的难点。

JSONP的长处是:它不像XMLHttpRequest对象完毕的Ajax请求那样受到同源策略的限定;它的包容性更好,在进一步古老的浏览器中都能够运维,不须求XMLHttpRequest或ActiveX的支持;并且在伸手完结后方可经过调用callback的点子回传结果。

  1. 通过CORS跨域

JSONP的短处则是:它只帮衬GET请求而不援助POST等其余品类的HTTP请求;它只补助跨域HTTP请求那种情状,不可能一举成功不相同域的八个页面之间什么开始展览JavaScript调用的难题。

COCRUISERS(克罗斯-Origin Resource
Sharing)跨域财富共享,定义了亟须在走访跨域能源时,浏览器与服务器应该怎么着联系。COOdysseyS背后的大旨理维正是行使自定义的HTTP底部让浏览器与服务器举行沟通,从而控制请求或响应是应当成功恐怕退步。近期,全体浏览器都补助该意义,IE浏览器不能够低于IE10。整个COLacrosseS通讯进度,都是浏览器自动完结,不必要用户参预。对于开发者来说,CO酷路泽S通讯与同源的AJAX通讯没互不相同,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自行抬高级中学一年级些外加的头新闻,有时还会多出一遍附加的伸手,但用户不会有觉得。

  1. 通过CORS跨域

故此,达成CO昂CoraS通讯的重庆大学是服务器。只要服务器完毕了COSportageS接口,就能够跨源通讯。

CO帕杰罗S(克罗丝-Origin Resource
Sharing)跨域财富共享,定义了必须在做客跨域能源时,浏览器与服务器应该怎样联系。CO帕杰罗S背后的主干考虑正是选择自定义的HTTP头部让浏览器与服务器进行沟通,从而控制请求或响应是相应成功只怕失利。最近,全部浏览器都协助该意义,IE浏览器无法低于IE10。整个CO纳瓦拉S通讯进程,都以浏览器自动完毕,不须要用户参与。对于开发者来说,CO汉兰达S通讯与同源的AJAX通讯无差异,代码完全一致。浏览器一旦发现AJAX请求跨源,就会活动抬高级中学一年级些叠加的头音信,有时还会多出2次附加的伸手,但用户不会有感觉。

平常的ajax请求恐怕是这么的:

为此,达成COHighlanderS通讯的显借使服务器。只要服务器达成了CO汉兰达S接口,就足以跨源通讯。

var xhr = new XMLHttpRequest();

毕生的ajax请求可能是那样的:

xhr.open(“POST”, “/damonare”,true);

var xhr = new XMLHttpRequest();

xhr.send();

xhr.open(“POST”, “/damonare”,true);

上述damonare部分是相对路径,要是大家要采取CO奇骏S,相关Ajax代码或然如下所示:

xhr.send();

var xhr = new XMLHttpRequest();

上述damonare部分是相对路径,假设大家要使用CO帕杰罗S,相关Ajax代码可能如下所示:

xhr.open(“GET”, “);

var xhr = new XMLHttpRequest();

xhr.send();

xhr.open(“GET”, “);

代码与事先的分别就在于相对路径换到了别的域的相对路径,也正是您要跨域访问的接口地址。

xhr.send();

劳动器端对于CORubiconS的支撑,主要正是通过设置Access-Control-Allow-Origin来展开的。要是浏览器检查和测试到对应的设置,就足以允许Ajax实行跨域的访问。关于CO帕杰罗S更加多询问能够看下阮一峰老师的这一篇小说:跨域财富共享
CO福特ExplorerS 详解

代码与前面包车型地铁界别就在于相对路径换到了其余域的相对路径,也便是你要跨域访问的接口地址。

CORS和JSONP对比

劳务器端对于COSportageS的支撑,主要就是经过设置Access-Control-Allow-Origin来开始展览的。若是浏览器检测到相应的装置,就足以允许Ajax举办跨域的造访。关于COSportageS愈多询问能够看下阮一峰老师的这一篇作品:跨域财富共享
CO福特ExplorerS 详解

JSONP只好兑现GET请求,而CO揽胜极光S援助具有品种的HTTP请求。

CORS和JSONP对比

运用COWranglerS,开发者能够运用普通的XMLHttpRequest发起呼吁和获取数据,比起JSONP有更好的错误处理。

JSONP只可以兑现GET请求,而CO中华VS协助全部类型的HTTP请求。

JSONP主要被老的浏览器扶助,它们往往不补助CO帕杰罗S,而大多数现代浏览器都曾经支撑了CO奥迪Q7S)。

使用CO中华VS,开发者能够应用普通的XMLHttpRequest发起呼吁和获得数量,比起JSONP有更好的错误处理。

CO宝马X5S与JSONP相比,无疑特别先进、方便和保障。

JSONP首要被老的浏览器帮助,它们往往不帮忙COTiguanS,而半数以上现代浏览器都早已补助了CO安德拉S)。

  1. 通过window.name跨域

CO翼虎S与JSONP比较,无疑更是先进、方便和保障。

window对象有个name属性,该属性有个性子:即在3个窗口(window)的生命周期内,窗口载入的拥有的页面都是共享3个window.name的,每一种页面对window.name都有读写的权柄,window.name是持久存在三个窗口载入过的全数页面中的,并不会因新页面包车型客车载入而展开重置。

  1. 通过window.name跨域

例如:大家在任意二个页面输入

window对象有个name属性,该属性有个特征:即在多少个窗口(window)的生命周期内,窗口载入的拥有的页面都以共享三个window.name的,每一种页面对window.name都有读写的权能,window.name是百折不回存在1个窗口载入过的具有页面中的,并不会因新页面包车型大巴载入而举行重置。

window.name = “My window’s name”;

例如:大家在肆意八个页面输入

setTimeout(function(){

window.name = “My window’s name”;

   window.location.href = “”;

setTimeout(function(){

},1000)

    window.location.href = “”;

进入damonare.cn页面后大家再检查和测试再检查和测试 window.name :

},1000)

window.name; // My window’s name

跻身damonare.cn页面后大家再检查和测试再检查和测试 window.name :

能够看看,假设在1个标签里面跳转网页的话,大家的 window.name
是不会变动的。

window.name; // My window’s name

据他们说这些思想,咱们能够在某些页面设置好 window.name
的值,然后跳转到其余三个页面。在那几个页面中就能够收获到咱们正好安装的
window.name 了。

能够看出,尽管在贰个标签里面跳转网页的话,大家的 window.name
是不会改变的。

鉴于安全原因,浏览器始终会保持 window.name 是string 类型。

依照这几个思想,咱们能够在有些页面设置好 window.name
的值,然后跳转到其余3个页面。在那一个页面中就能够赢获得大家恰好安装的
window.name 了。

一致这一个情势也得以使用到和iframe的交互来:

出于安全原因,浏览器始终会维持 window.name 是string 类型。

诸如:小编的页面(

同一这些格局也足以使用到和iframe的互相来:

在 iframe.html 中设置好了 window.name 为大家要传送的字符串。

譬如说:笔者的页面(

咱俩在 index.html 中写了下边包车型大巴代码:

在 iframe.html 中装置好了 window.name 为我们要传递的字符串。

var iframe = document.getElementById(‘iframe’);

大家在 index.html 中写了下边包车型大巴代码:

var data = ”;

var iframe = document.getElementById(‘iframe’);

iframe.onload = function() {

var data = ”;

data = iframe.contentWindow.name;

iframe.onload = function() {

};

data = iframe.contentWindow.name;

Boom!报错!肯定的,因为多个页面分化源嘛,想要解决这些难题得以如此干:

};

var iframe = document.getElementById(‘iframe’);

Boom!报错!肯定的,因为四个页面分歧源嘛,想要化解那一个题材得以这么干:

var data = ”;

var iframe = document.getElementById(‘iframe’);

iframe.onload = function() {

var data = ”;

iframe.onload = function(){

iframe.onload = function() {

data = iframe.contentWindow.name;

iframe.onload = function(){

}

data = iframe.contentWindow.name;

iframe.src = ‘about:blank’;

}

};

iframe.src = ‘about:blank’;

抑或将中间的 about:blank 替换到有个别同源页面(about:blank,javascript: 和
data: 中的内容,继承了载入他们的页面包车型大巴源。)

};

那种格局与 document.domain
方法相比较,放宽了域名后缀要一如既往的限量,能够从随机页面得到 string
类型的数量。

大概将中间的 about:blank 替换来有些同源页面(about:blank,javascript: 和
data: 中的内容,继承了载入他们的页面包车型大巴源。)

那种办法与 document.domain
方法比较,放宽了域名后缀要一如既往的限定,能够从随机页面得到 string
类型的多寡。

后记

别的诸如中间件跨域,服务器代理跨域,Flash
U酷路泽LLoader跨域,动态成立script标签(简化版本的jsonp)不作探讨。

 

 

 

 

发表评论

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

网站地图xml地图