跨了个域——冷门篇

这篇我们讲跨域的几个冷门方法,如果想从头开始可以点击跨了个域第一篇

postMessage大法:跨文档信息传送(cross-document messaging),有时简称为XMD,指的是在来自不同域的页面间传递信息。

XDM的核心是postMessage()方法。对于XDM而言,通常指的是包含在当前页面中的<iframe>元素,或者由当前页面弹出的窗口

这个页面所在的位置是http://127.0.0.1/demo.html,引入了http://127.0.0.1/test.html,不造成跨域,但为的就是先看不跨越正常使用的效果

// http://127.0.0.1/demo.html
<iframe src="http://127.0.0.1/test.html" frameborder="0" id="iframe"></iframe>
<script>
    var haha = 1234;
    window.onload = function () {
	    var iframeWindow = document.getElementById('iframe').contentWindow;   // 获取引用window
	    console.log(iframeWindow, iframeWindow.myName);
	    iframeWindow.postMessage({ name: 'mike' }, 'http://127.0.0.1');	// 发送信息
    }
</script>


// http://127.0.0.1/test.html
<script>
    var myName = 'child';
    window.addEventListener('message', function (event) {
      console.log(event.data);    // 传输的信息
      console.log(event.origin);	// 发送信息的文档所在的域
      console.log(event.source, event.source.haha);  // 发送信息的window对象
      // 可以再利用event.socuce.postMessage一次,但这样发送的,当进入event.source时,window对象就会变成自己
    })
</script>

现在看浏览器所输出

可以从打印中看到可以拿到对应的window对象,也输出了传递的值;

现在看跨域的情况:引入不同端口的页面

// http://127.0.0.1/demo.html
<iframe src="http://127.0.0.1:361/src/index2.html" frameborder="0" id="iframe"></iframe>
<script>
	var haha = 1234;
	window.onload = function () {
		var iframeWindow = document.getElementById('iframe').contentWindow;   // 获取引用window
		console.log(iframeWindow, iframeWindow.nam);
		iframeWindow.postMessage({ name: 'mike' }, 'http://127.0.0.1:361');	// 发送信息
	}
</script>

// http://127.0.0.1:361/src/index2.html
<script>
    var myName = 'child';
    window.addEventListener('message', function (event) {
      console.log(event.data);    // 传输的信息
      console.log(event.origin);	// 发送信息的文档所在的域
      console.log(event.source, event.source.haha);  // 发送信息的window对象
      // 可以再利用event.socuce.postMessage一次,但这样发送的,当进入event.source时,window对象就会变成自己
    })
</script>

浏览器输出:

记住这个信息并不是不能达到跨域,只是不让你去访问对应的window对象了而已,我们把window都删掉

// http://127.0.0.1/demo.html
<iframe src="http://127.0.0.1:361/src/index2.html" frameborder="0" id="iframe"></iframe>
<script>
	var haha = 1234;
	window.onload = function () {
		var iframeWindow = document.getElementById('iframe').contentWindow;   // 获取引用window
		iframeWindow.postMessage({ name: 'mike' }, 'http://127.0.0.1:361');	// 发送信息
	}
</script>


// http://127.0.0.1:361/src/index2.html
<script>
    var myName = 'child';

    window.addEventListener('message', function (event) {
      console.log(event.data);    // 传输的信息
      console.log(event.origin);	// 发送信息的文档所在的域
    })
</script>

浏览器输出:

一样可以拿到传递的值,但跨域的限制就是:只能拿到传递的值,不能拿到window对象;你要是说那把window传递过去不就行了,其实还是会被浏览器拦截~

使用open打开的就不展示了,也是一样用postMessage传递,不跨越正常使用;跨域则不使用去获取对方的window则不报错;(还有一种情况是拿到对方的window,但却不用获取window上挂载的自定义变量)

这里顺带一提,如果我们使用a链接并且用_blank方式打开的窗口(同源),我们也可以在这个打开的窗口使用window.opener查看主页面的信息,虽然对访问有所限制(不能访问到挂载的自定义变量),但还是有漏网之鱼

比如我给你来个:opener.location = 'http://cf.qq.com/index.shtml',你就完全没心思学习,甚至想打cf!因为已经改变了你的主窗口跳转;

<a href="http://127.0.0.1/test.html" target="_blank" rel="noopener">哈哈</a>

我们可以使用rel="noopener"改变,让被打开窗口的opener变成null;

document.name+ iframe大法

这个方法会稍稍有点绕,但看好步骤就不那么难了;

记住,核心即为window.name,因为name有一个特性就是在不同页面或者不同域下加载后依旧存在,没有修改就不会发生变化!

觉得虚幻的同学可以试试随便打开一个页面后,开F12手动修改name,然后随便在本窗口打开别的页面(一定在本窗口打开,不能打开新窗口),然后你会发现这个窗口的name还是你刚刚设置的name~

首先准备三个页面:

主页面

proxy空页面(为了规避策略)

需要跨域的页面设置好name

// index2.html - 需要获取信息的页面设置好name
<script>
      window.name = 'I am index2!'; 
</script>

<script>
	var iframe = document.createElement('iframe');
	iframe.style.display = 'none';
	var state = 0;

	iframe.onload = function () {
		if (state === 1) {
			var data = iframe.contentWindow.name;
			console.log(data)  // 4.接着就拿到了需要的数据
			iframe.contentWindow.close();  // 关闭window,页面就不会存在iframe框
			document.body.removeChild(iframe);  // 删除节点
		} else if (state === 0) {
			state = 1;
			iframe.contentWindow.location = './proxy.html';  // 3.当加载完成后立即跳转成本服务器的一个页面(没有跨域问题)
		}
	};

	iframe.src = 'http://localhost:361/src/index2.html';  // 1.这个是需要跨域的地址
	document.body.appendChild(iframe);  // 2.插入body后立即生效

</script>

剩下的还有 document.domain + iframe 跨域 location.hash + iframe 跨域没有介绍,这里也就不多介绍了~

这两个方法可以自行百度参考。我喜欢的还是够用就行~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值