「JavaScript」JS四种跨域体式格局详解

超细致而且带 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

运用前提:

  1. 有其他页面 window 对象的援用。
  2. 二级域名雷同。
  3. 协定雷同。
  4. 端口雷同。

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.namestring 范例。

这个要领也能够应用到与 <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:blankjavascript: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要领请点这里

以为不错的话按顶部的引荐,让更多人看到吧~ㄟ(▔▽▔ㄟ)

    原文作者:JasonKidd
    原文地址: https://segmentfault.com/a/1190000003642057
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞