超细致而且带 Demo 的 JavaScript 跨域指南来了!
本文基于你相识 JavaScript 的同源战略,而且相识运用跨域跨域的来由。
1. JSONP
首先要引见的跨域要领必定是 JSONP。
如今你想要猎取其他网站上的 JavaScript 剧本,你异常高兴的运用 XMLHttpRequest 对象来猎取。然则浏览器一点儿也不合营你,无情的弹出了下面的错误信息:
XMLHttpRequest cannot load http://x.com/main.dat. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://y.com' is therefore not allowed access.
你内心一定会想,我岂非要用背景做个爬虫来猎取这个数据吗?!(;°○° )
为了防止这类蛋疼的事变发作,JSONP 就派上用场了。
<script>
标签是不受同源战略的限定的,它能够载入恣意处所的 JavaScript 文件,而并不要求同源。
所以 JSONP 的理念就是,我和服务端商定好一个函数名,当我要求文件的时刻,服务端返回一段 JavaScript。这段 JavaScript 调用了我们商定好的函数,而且将数据当作参数传入。
异常偶合的一点(实在并非),JSON 的数据花样和 JavaScript 言语里对象的花样恰好雷同。所以在我们商定的函数内里能够直接运用这个对象。
言而不行假把式,让我们来看一个例子:
你须要猎取数据的页面 index.html:
<script>
function getWeather(data) {
console.log(data);
}
</script>
<script src="http://x.y.com/xx.js">
http://x.y.com/xx.js 文件内容:
getWeather({
"都市": "北京",
"天色": "大雾"
});
我们能够看到,在我们定义了 getWeather(data)
这个函数后,直接载入了 xx.js。
在这个剧本中,实行了 getWeather
函数,并传入了一个对象。然后我们在这个函数中将这个对象输出到 console 中。
这就是全部 JSONP 的流程。
2. document.domain
运用前提:
- 有其他页面
window
对象的援用。 - 二级域名雷同。
- 协定雷同。
- 端口雷同。
document.domain
默许的值是全部域名,所以纵然两个域名的二级域名一样,那末他们的 document.domain
也不一样。
运用要领就是将相符上述前提页面的 document.domain
设置为一样的二级域名。如许我们就能够运用其他页面的 window
对象援用做我们想做的任何事变了。(╯▔▽▔)╯
补充学问:
- x.one.example.com 和 y.one.example.com 能够将
document.domain
设置为 one.example.com,也能够设置为 example.com。document.domain
只能设置为当前域名的一个后缀,而且包含二级域名或以上(.edu.cn
这类全部算顶级域名)。
我们直接操刀演示,用两个网站 http://wenku.baidu.com/ 和 http://zhidao.baidu.com/。
这两个网站都是 http
协定,端口都是 80, 且二级域名都是 baidu.com。
翻开 http://wenku.baidu.com/,在 console 中输入代码:
document.domain = 'baidu.com';
var otherWindow = window.open('http://zhidao.baidu.com/');
我们如今已发明百度晓得的网页已翻开了,在百度晓得网页的 console 中输入以下代码:
document.domain = 'baidu.com';
如今回到百度文库的网页,我们就能够运用百度晓得网页的 window
对象来操纵百度晓得的网页了。比方:
var divs = otherWindow.document.getElementsByTagName('div');
上面这个例子的运用要领并不罕见,然则异常细致的说清楚明了这类要领的道理。
这类要领重要用在掌握 <iframe>
的状况中。
比方我的页面(http://one.example.com/index…. <iframe>
:
<iframe id="iframe" src="http://two.example.com/iframe.html"></iframe>
我们在 iframe.html 中运用 JavaScript 将 document.domain
设置好,也就是 example.com。
在 index.html 实行以下剧本:
var iframe = document.getElementById('iframe');
document.domain = 'example.com';
iframe.contentDocument; // 框架的 document 对象
iframe.contentWindow; // 框架的 window 对象
如许,我们就能够取得对框架的完整掌握权了。
补充学问(相对干货):
当两个页面不做任何处置惩罚,然则运用了框架或许window.open()
得到了某个页面的window
对象的援用,我们能够直接接见的属性有哪些?
要领 window.blur
window.close
window.focus
window.postMessage
window.location.replace
属性 权限 window.closed
只读 window.frames
只读 window.length
只读 window.location.href
只写 window.opener
只读 window.parent
只读 window.self
只读 window.top
只读 window.window
只读
3. window.name
我们来看以下一个场景:
随便翻开一个页面,输入以下代码:
window.name = "My window's name";
location.href = "http://www.qq.com/";
再检测 window.name
:
window.name; // My window's name
能够看到,如果在一个标签内里跳转网页的话,我们的 window.name
是不会转变的。
基于这个头脑,我们能够在某个页面设置好 window.name
的值,然后跳转到别的一个页面。在这个页面中就能够猎取到我们方才设置的 window.name
了。
因为平安缘由,浏览器始终会坚持
window.name
是string
范例。
这个要领也能够应用到与 <iframe>
的交互上来。
我的页面(http://one.example.com/index…. <iframe>
:
<iframe id="iframe" src="http://omg.com/iframe.html"></iframe>
在 iframe.html 中设置好了 window.name
为我们要通报的字符串。
我们在 index.html 中写了下面的代码:
var iframe = document.getElementById('iframe');
var data = '';
iframe.onload = function() {
data = iframe.contentWindow.name;
};
定睛一看,为毛线报错?
仔细的读者们一定已发清楚明了,两个页面完整差别源啊!
因为 window.name 不跟着 URL 的跳转而转变,所以我们运用一个暗黑手艺来处理这个题目:
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
范例的数据。
4. [HTML5] postMessage
在 HTML5 中, window
对象增加了一个异常有效的要领:
windowObj.postMessage(message, targetOrigin);
-
windowObj
: 吸收音讯的 Window 对象。 -
message
: 在最新的浏览器中能够是对象。 -
targetOrigin
: 目的的源,*
示意恣意。
这个要领异常壮大,疏忽协定,端口,域名的差别。下面是烤熟的栗子:
var windowObj = window; // 能够是其他的 Window 对象的援用
var data = null;
addEventListener('message', function(e){
if(e.origin == 'http://jasonkid.github.io/fezone') {
data = e.data;
e.source.postMessage('Got it!', '*');
}
});
message
事宜就是用来吸收 postMessage
发送过来的要求的。函数参数的属性有以下几个:
-
origin
: 发送音讯的window
的源。 -
data
: 数据。 -
source
: 发送音讯的Window
对象。
Demo
https://github.com/JasonKid/f…
两种服务端相干跨域要领
「JavaScript」两种服务端相干跨域要领详解 ← 反向代办、CORS要领请点这里
以为不错的话按顶部的引荐,让更多人看到吧~ㄟ(▔▽▔ㄟ)