4种通过iframe跨域与其他页面通信的方式

news2024/12/27 12:53:08

目录

4种通过iframe跨域与其他页面通信的方式

location.hash

window.name

postMessage

document.domain降域


4种通过iframe跨域与其他页面通信的方式

location.hash

        在url中,http://www.baidu.com#helloword#helloworad就是location.hash,改变hash值不会导致页面刷新,所以可以利用hash值来进行数据的传递,当然数据量是有限的。 假设localhost:8080下有文件cs1.html要和localhost:8081下的cs2.html传递消息,cs1.html首先创建一个隐藏的iframe,iframe的src指向localhost:8081/cs2.html,这时的hash值就可以做参数传递。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CS1</title>
</head>
<body>
    <script>
    // http://localhost:8080/cs1.html
    let ifr = document.createElement('iframe');
    ifr.style.display = 'none';
    ifr.src = "http://localhost:8081/cs2.html#data";
    document.body.appendChild(ifr);
        
    function checkHash() {
        try {
        //去掉?
        let data = location.hash ? location.hash.substring(1) : ' ';
        console.log('获得到的数据是:', data);
        }catch(e) {

        }
    }
    window.addEventListener('hashchange', function(e) {
        console.log('获得的数据是:', location.hash.substring(1));
        });
    </script>
</body>
</html>

        cs2.html收到消息后通过parent.location.hash值来修改cs1.html的hash值,从而达到数据传送。

</head>
<body>
    <script>
    // http://locahost:8081/cs2.html
    switch(location.hash) {
        case "#data":
        callback();
        break;
    }
    function callback() {
    const data = "some number: 1111"
    try {
        parent.location.hash = data;
    }catch(e) {
        // ie, chrome 下的安全机制无法修改 parent.location.hash
        // 所以要利用一个中间的代理 iframe 
        var ifrproxy = document.createElement('iframe');
        ifrproxy.style.display = 'none';
        ifrproxy.src = 'http://localhost:8080/cs3.html#' + data;     // 该文件在请求域名的域下
        document.body.appendChild(ifrproxy);
        }
       }
    </script>
</body>
</html>

        由于两个页面不在同一个域下,所以浏览器不允许修改parent.location.hash的值,所以要借助于localhost:8080域名下的一个代理iframe的cs3.html页面

<script>
    parent.parent.location.hash = self.location.hash.substring(1)
</script>

        打开服务器

         之后打开浏览器访问localhost:8080/cs1.html(不是8081),就可以看到获取到的数据了,此时页面的hash值已经改变了。

         hash的值已经更改.PNG

缺点:

  • 数据直接暴露在了url中

  • 数据容量和类型都有限

window.name

        window.name(一般在js代码里出现)的值不是一个普通的全局变量,而是当前窗口的名字,要注意的是每个iframe都有包裹它的window,而这个window是top window的子窗口,而它自然也有window.name的属性,window.name属性的神奇之处在于name值在不同的页面(甚至不同域名)加载后依旧存在(如果没有修改则值不会变化),并且可以支持非常长的name值(2MB) 举个简单的例子:你在某个页面的控制台输入:

window.name = "hello world"
window.location = "http://www.baidu.com"

        页面跳转到了百度首页,但是window.name却被保存下来了,还是Hhello world。

首先创建 a.html 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>a.html</title>
</head>
<body>
    <script>
    let data = '';
    const ifr = document.createElement('iframe');
    ifr.src = "http://localhost:8081/b.html";
    ifr.style.display = 'none';
    document.body.appendChild(ifr);
    ifr.onload = function() {
        ifr.onload = function() {
            data = ifr.contentWindow.name;
        console.log('收到数据:', data);
        }
        ifr.src = "http://localhost:8080/c.html";
    }
    </script>
</body>
</html>

        再创建 b.html 文件:

<script>
   window.name = "你想要的数据!";
</script>

        http://localhost:8080/a.html在请求远端服务器http://localhost:8081/b.html的数据,我们可以在该页面下新建一个iframe,该iframe的src属性指向服务器地址(利用iframe标签的跨域能力),服务器文件b.html设置好window.name值。

        但是由于a.html页面和该页面iframe的src不同源的话,则无法操作iframe里的任何东西,所以就取不到iframe的name值,所以我们需要在b.html加载完之后重新换个src区指向一个同源的html文件,或者设置成about:blank都行,这时候我们只要在a.html相同的目录下件一个c.html空白即可。如果不重新指向src的话直接获取的window.name的话就会报错。

postMessage

        postMessage 是 HTML5 新增加的一项功能,跨文档消息传输(Cross Document Messaging),目前:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 都支持这项功能。

首先创建 a.html 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>a.html</title>
</head>
<body>
    <iframe src="http://localhost:8081/b.html" style='display: none;'></iframe>
    <script>
    window.onload = function() {
        let targetOrigin = 'http://localhost:8081';
      //想要操作当前iframe的时候,就像该ifranme中postMessage()一个东西。
        window.frames[0].postMessage('我要给你发消息了!', targetOrigin);
        //*表示任何域都可以监听。
    }
      //当我监听到message事件的时候,我就知道有人向我发送数据了,我获得了数据就可以做对应的事情。内部对消息做实现
    window.addEventListener('message', function(e) {
        console.log('a.html 接收到的消息:', e.data);
    });
    </script>
</body>
</html>

        创建一个 iframe,使用 iframe 的一个方法 postMessage 可以向http://localhost:8081/b.html发送消息,然后监听 message,可以获得其他文档发来的消息。

同样的 b.html 文件:

<script> 
window.addEventListener('message', function(e) { 
    if(e.source != window.parent) { 
        return; 
    } 
    let data = e.data;
    console.log('b.html 接收到的消息:', data); 
    parent.postMessage('我已经接收到消息了!', e.origin); 
})
</script>

document.domain降域

        对于主域相同而子域不同的情况下,可以通过设置 document.domain 的办法来解决,具体做法是可以在 http://www.example.com/a.htmlhttp://sub.example.com/b.html两个文件分别加上 document.domain = "example.com";然后通过 a.html 文件创建一个 iframe,去控制 iframe 的 window,从而进行交互,当然这种方法只能解决主域相同而二级域名不同的情况,如果你异想天开的把 script.example.com 的 domain 设为 qq.com 显然是没用的,那么如何测试呢?

         测试的方式稍微复杂点,需要安装 nginx 做域名映射,如果你电脑没有安装 nginx,请先去安装一下: nginx news 前提:两个域名后面的东西是一样的。

先创建一个 a.html 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>a.html</title>
</head>
<body>
    <script>
    //document.domain让当前的域进行降域,这样二者就可以实现相互操作和访问了。
    document.domain = 'example.com';
    let ifr = document.createElement('iframe');
    ifr.src = 'http://sub.example.com/b.html';
    ifr.style.display = 'none';
    document.body.append(ifr);
    ifr.onload = function() {
        let win = ifr.contentWindow;
        alert(win.data);
    }
    </script>
</body>
</html>

再创建一个 b.html 文件:

<script>
    document.domain = 'example.com';
    window.data = '传送的数据:1111';
</script>

        这时只是开启了两个 http 服务器,还需要通过 nginx 做域名映射,将Example Domain映射到 localhost:8080sub.example.com 映射到 localhost:8081

打开操作系统下的 hosts 文件:mac 是位于 /etc/hosts 文件,并添加:

127.0.0.1 www.example.com
127.0.0.1 sub.example.com

        这样在浏览器打开这两个网址后就会访问本地的服务器。

之后打开 nginx 的配置文件:/usr/local/etc/nginx/nginx.conf,并在 http 模块里添加:

server {
    listen 80;
    server_name www.example.com;
    location / {
        proxy_pass http://127.0.0.1:8080/;
    }
}
server {
    listen 80;
    server_name sub.example.com;
    location / {
        proxy_pass http://127.0.0.1:8081/;
    }
}

        上面代码的意思是:如果访问本地的域名是Example Domain就由 localhost:8080 代理该请求。

        所以我们这时候在打开浏览器访问Example Domain的时候其实访问的就是本地服务器 localhost:8080。

 转自iFrame跨域的方式 - HappyVK - 博客园

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/194587.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringMVC之bean加载控制

目录 一&#xff1a;问题分析 二&#xff1a;思路分析 三&#xff1a;环境准备 四&#xff1a;设置bean加载控制 知识点1&#xff1a;ComponentScan 一&#xff1a;问题分析 入门案例的内容已经做完了&#xff0c;在入门案例中我们创建过一个SpringMvcConfig的配置类&#x…

Redis如何实现分布式锁?

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【一心同学】&#xff0c;一位上进心十足的【Java领域博主】&#xff01;&#x1f61c;&#x1f61c;&#x1f61c; ✨【一心同学】的写作风格&#x…

OpenMMLab学习笔记(一)

OpenMMLab学习笔记&#xff08;一&#xff09; day01 计算机视觉与OpenMMLab开源算法体系 1. 基本知识 计算机视觉的基础任务&#xff1a;分类、分类和定位、物体检测、分割&#xff08;语义分割、实例分割&#xff09;&#xff0c;其中实例分割统一种类索引不同 注意语义分…

indexedDB存储

一、概述 随着浏览器的功能不断增强&#xff0c;越来越多的网站开始考虑&#xff0c;将大量数据储存在客户端&#xff0c;这样可以减少从服务器获取数据&#xff0c;直接从本地获取数据。 现有的浏览器数据储存方案&#xff0c;都不适合储存大量数据&#xff1a;Cookie 的大小…

rocketmq 笔记

cap理论 Consistency&#xff08;一致性&#xff09;Availability&#xff08;可用性&#xff09;Partition tolerance&#xff08;分区容忍性&#xff09; ①一致性&#xff1a;对于客户端的每次读操作&#xff0c;要么读到的是最新的数据&#xff0c;要么读取失败。换句话说…

ElasticSearch -- Prometheus+Grafana监控

向导介绍部署Prometheus配置Grafana下载仪表盘导入仪表盘报警核心指标集群健康和节点可用性主机级别的系统和网络指标JVM内存和垃圾回收搜索和索引性能资源饱和度注册自动重启介绍 Prometheus官方提供了ES的exporter&#xff1a;EsExporter Github地址&#xff1a;elasticsea…

【Vue】Vue不同版本的基本使用

一、Vue的版本 1. Vue1.x几乎被淘汰&#xff0c;不再建议学习与使用。2. Vue2.x<scriptsrc"" target"_blank">https://cdn.jsdelivr.net/npm/vue2.6.14"></script>3. Vue3.x<scriptsrc"" target"_blank">ht…

【IO异常】HTTP请求报错Error writing to server

报错信息如下&#xff1a; [2023-01-04 13:36:02.185]-ERROR-[biz:aplus-task-oms1060189862335877121][sys:aplus-cms-tran1060189866052390912][com.phfund.aplus.cms.tran.module.counter.service.impl.OcrServiceImpl-102][调用远程服务发送文件异常:] cn.hutool.http.Http…

一、HTML5

文章目录一、HTML5二、html5的基本结构三、基本标签四、HTML常用标记4.1 文本标题(h1-h6)4.2 段落文本p4.4 空格4.5 换行 br4.6 水平线4.7 加粗标记4.8 倾斜4.9 扩展4.10 列表4.10.1 ul 无序列表4.10.2 ol 有序列表4.10.3 dl 自定义列表五、块级标签、行级标签一、HTML5 H5是H…

洛谷 P1886 滑动窗口 /【模板】单调队列

滑动窗口 /【模板】单调队列 题目描述 有一个长为 nnn 的序列 aaa&#xff0c;以及一个大小为 kkk 的窗口。现在这个从左边开始向右滑动&#xff0c;每次滑动一个单位&#xff0c;求出每次滑动后窗口中的最大值和最小值。 例如&#xff1a; The array is [1,3,−1,−3,5,3,…

辨别三星内存条的真假

目录前言一、三星内存为什么水深&#xff1f;二、通过物理手段辨别1.包装2.日期3.是否透光4.颜色5.电阻颜色6.颗粒丝印&#xff08;重点&#xff09;7.其他标签或字迹结语前言 本文截止2023.2.2&#xff0c;针对笔记本内存条 省流&#xff1a;直接JD自营 最近随手在tb买了条三星…

快速掌握任意 Android 应用的抓包

抓包是流量分析的基础&#xff0c;也是安全研究重要的一环。抓包软件有很多种&#xff0c;如 Burpsuite、mitmproxy 以及 Fiddle&#xff0c;抓包方式常见的有设置系统代理、AP 热点抓包、透明代理等。不同方式有不同优缺点&#xff0c;也有不同的应用场景。相信很多安全研究者…

Google Analytics | 学习笔记

一.简介 1.什么是GA&#xff1f; 是谷歌开发的一款分析网页流量的工具&#xff0c;可以帮助网站解决数据分析与统计的问题&#xff0c;并且将这些数据可视化展现报告出来&#xff0c;帮助网站商家更好的分析受众&#xff0c;流量等&#xff0c;从而更好地进行运营网站营销等 …

UV统计的学习

12.1 、UV统计-HyperLogLog 首先我们搞懂两个概念&#xff1a; UV&#xff1a;全称Unique Visitor&#xff0c;也叫独立访客量&#xff0c;是指通过互联网访问、浏览这个网页的自然人。1天内同一个用户多次访问该网站&#xff0c;只记录1次。 PV&#xff1a;全称Page View&am…

大龄考生上岸浙大MPA的“曲线救国”策略

先来介绍一下我个人的背景把&#xff0c;我是通过参加浙大提前批面试获得A资格&#xff0c;笔试接近两百分上岸MPA项目的。说起来我的个人优势真的不多&#xff0c;只是一个普通一本&#xff0c;不是什么211/985的名校&#xff0c;所以就对浙大有一种向往&#xff0c;使得自己的…

【数据结构】1.4 算法和算法分析

文章目录1. 算法的定义及特性算法的特性算法设计的要求2. 算法的时间复杂度分析算法时间复杂度的基本方法算法时间复杂度分析例题算法时间复杂度的计算3. 算法的空间复杂度1. 算法的定义及特性 算法的定义 对特定问题求解方法和步骤的一种描述&#xff0c;它是指令的有限序列…

C++:String类应用

string对象的构造 //string() string(const string &s) string(const char *s) string(first,last) void TestString01() {string s1;string s2("hello");string s3(s2);const char* p "hello";string s4(p, p 2);cin >> s1;cout << …

微信小程序 Springboot旅游景点酒店预订管理系统 java

功能模块划分 &#xff08;1&#xff09;用户信息管理模块 用户管理模块主要是对用户信息进行管理。包括&#xff1a; 用户的注册&#xff1a;实现用户信息的注册&#xff0c;用户注册是的信息校验&#xff0c;用户信息的保存。 用户的登录&#xff1a;检验用户是否为该网站的合…

如何打造优秀高绩效的团队?Google亚里士多德计划揭开谜底!

研究人员通过亚里士多德计划开展研究&#xff0c;通过对大量团队效率进行定性&#xff08;360主观评估&#xff09;与定量&#xff08;产出成果度量&#xff09;结合的统计评估&#xff0c;筛选出左右着团队动态的五个关键支柱&#xff1a;心理安全、可靠性、结构和清晰度、意义…

Nginx与Upstream之间产生大量TIME_WAIT连接的解决办法

1. 现象 Nginx反向代理了一个Java服务&#xff0c;QPS大概是200&#xff0c;问题发生时的Nginx配置&#xff1a; location / {proxy_pass http://192.168.3.4:18600; }在上游Java服务器上可以观察到大量&#xff08;约2000个&#xff09;的TIME_WAIT状态的网络连接 从Nginx…