iframe 这个标签之前了解过这个东西, 知道它可以引入外来的网页, 但是实际开发中没有用到过. 这一次有一个需求是说准备要在网页中嵌套另外一个网站, 用 iframe 这个标签, 让我测试一下这个可不可以在自己的网页中对引入进来的 iframe 框架进行操作, 操作 dom 和 CSS 的一些东西. 让我做出一个小案例看看可不可以, 我信誓旦旦保证说可以的, 我试过!!!
就这样交代给我之后信心满满的就开始了我的验证.
什么是同源?
同域名, 同端口, 同协议
网上是有好多这个的解释的, 给出一张图片. 看下面这张图片. 引用来自 浏览器的同源策略
我直接新建了一个文件夹, 在里面写了两个 html 页面的文件, 举例说明是 a.HTML 和 b.HTML, 然后让其中的一个 a.HTML 文件中用 iframe 标签的 src 去引入 b.HTML 文件, 在里面去互相操作他们的 CSS 样式和 DOM 元素.
a.HTML
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- HTML,body{
- height: 100%;
- }
- body{
- background: pink;
- }
- #iframe1{
- width: 400px;
- height: 400px;
- margin: auto;
- background: blue;
- }
- </style>
- </head>
- <body>
这里是父文档
- <input type="button" id="btn1" value="改变子文档的颜色">
- <input type="button" id="btn2" value="删除 span1">
- <input type="button" id="btn3" value="改变 span2 的颜色">
- <input type="button" id="btn4" value="修改子文档中的 link 标签">
- <br />
- <br />
- <hr />
- <iframe id="iframe1" src="b.HTML" frameborder="0">
- </iframe>
- <script>
- // 只有同服务器下 同域名下才可以操作 不能更改别人的网页..
- var oBtn1 = document.getElementById('btn1');
- var oIframe1 = document.getElementById('iframe1');
- function fn(){
- document.body.style.background = 'green';
- }
- oBtn1.onclick = function () {
- console.log(oIframe1.contentWindow); // --- 这个东西是子文档中的 Windows 对象
- console.log(oIframe1.contentDocument); // ---- 这个东西是子文档中的 document 对象
- oIframe1.contentWindow.document.body.style.background = 'yellow';
- };
- btn2.onclick = function () {
- var span1 =oIframe1.contentWindow.document.querySelector('.span1');
- console.log(span1);
- span1.parentNode.removeChild(span1);
- };
- btn3.onclick = function () {
- var span2 =oIframe1.contentWindow.document.querySelector('.span2');
- span2.style.color = 'red';
- };
- btn4.onclick = function () {
- var iFrameWindow = oIframe1.contentWindow;
- console.log(iFrameWindow.document.getElementsByTagName('link'));
- var link0 = iFrameWindow.document.getElementsByTagName('link')[0];
- console.log(link0.parentNode.removeChild(link0));
- }
- </script>
- </body>
- </HTML>
b.HTML
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- body{
- background: yellowgreen;
- }
- </style>
- <link rel="stylesheet" href="1.CSS">
- <link rel="stylesheet" href="2.CSS">
- </head>
- <body>
- <h1 id="h1"> 这里是子文档 1</h1>
- <span class="span1">span1 标签 </span> <br>
- <br>
- <span class="span2">span2 标签 </span>
- <span class="span3">span3 标签 </span>
- <br />
- <hr />
- <input type="button" id="btn1" value="改变父文档的颜色">
- <script>
- var oH1 = document.getElementById('h1');
- var oBtn1 = document.getElementById('btn1');
- oH1.onclick = function () {
- alert('子文档中的点击事件, 我可以改变父文档');
- console.log(Windows.parent); // ----- 这个 parent 对象是父文档中的 Windows 对象
- };
- oBtn1.onclick = function () {
- (function (Windows,document) {
- document.body.style.background = 'skyblue';
- })(Windows.parent, Windows.parent.document);
- };
- </script>
- </body>
- </HTML>
样式如下
上面的两个代码中用到了一个东西, 在 a.HTML 文件中 用到了 iframe 标签元素的 .contentWindow 和 .contentDocument 这两个东西, 它们两个分别是子文档也就是 b.HTML 中的 Windows 对象和 document 对象, 那么你说知道了这两个东西要去操作它里面的东西还不简单吗.
在 b.HTML 文件中的 Windows.parent 这个东西是 a.HTML 的 Windows 对象, 那么它同样也可以去操作 a.HTML 中的元素了. 所以交给我的任务我感觉完成了, 就去问他, 这样可以. 然后我给他看了一下这个东西, 后来了解到这两个不是同一个域名下的, 这两个网站不是在一起的, 然后我就回来又来调试.
不同端口下的调试
我经常用的编辑器是 webstrom, 它这个东西会自启动一个 127.0.0.1:63342 的端口, 我又用 node 做了一个简单的监听 3000 端口的服务器, 在网页上面打开了.
还是同样的代码吧, 只不过把 ifreme 上面的 src 改为了我 3000 端口的网页.
- document.getElementById("myIFrame").contentWindow.document
- // Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.
- Windows.parent.document.body
- // 报错
- Windows.location.hash; // 这个是可以获取 hash 值的
- Windows.onhashchange = function(){
- // 这个是 hash 值改变会触发这个函数
- }
- btn1.onclick = function () {
- console.log(parent.location);
- }
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- body{
- background: pink;
- }
- #iframe1{
- width: 100%;
- height: 400px;
- }
- </style>
- </head>
- <body>
- <input type="button" id="btn1" value="改变子文档的东西">
- <input type="button" id="btn2" value="删除 span1 的颜色">
- <input type="button" id="btn3" value="改变 span2 的颜色">
- <br />
- <hr />
- <!--<iframe id="iframe1" src="http://localhost:3000" frameborder="0"></iframe>-->
- <iframe id="iframe1" src="http://localhost:3000" frameborder="0"></iframe>
- <script>
- var oIframe1 = document.getElementById('iframe1');
- var a = function fn(){
- document.body.style.background = 'green';
- };
- btn1.onclick = function () {
- console.log('传递的数据是','messageInfo');
- oIframe1.contentWindow.postMessage('changeColor',"http://localhost:3000");
- };
- btn2.onclick = function () {
- //oIframe1.contentWindow.postMessage('changeSpan2Color',"http://localhost:3000");
- oIframe1.contentWindow.postMessage('deleteSpan1',"http://localhost:3000")
- };
- btn3.onclick = function () {
- oIframe1.contentWindow.postMessage('changeSPan2Color',"http://localhost:3000")
- };
- Windows.addEventListener('message',function (res) {
- console.log(` 这里是父文档 `);
- if(res.data == 'GetWhiteLabel')
- document.body.style.background = 'yellow';
- })
- </script>
- </body>
- </HTML>
- <!doctype HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport"
- content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <title>Document</title>
- <style>
- body{
- background: skyblue;
- }
- </style>
- </head>
- <body>
- <h1 > 这里是我的 HTML 页面呢 </h1>
- <span class="span1">span1 标签 </span>
- <span class="span2">span2 标签 </span> <br>
- <input type="button" id="btn1" value="改变父文档的东西">
- <script>
- <!---->
- Windows.onload = function () {
- let parent = Windows.parent;
- Windows.addEventListener('message',function (res) {
- console.log(`****************** 这里是子页面的接收到的消息 *************`);
- console.log(res);
- switch (res.data) {
- case 'changeColor':
- document.body.style.background = 'green';
- break;
- case 'deleteSpan1':
- var oSpan1 = document.querySelector('.span1');
- oSpan1.parentNode.removeChild(oSpan1);
- break;
- case 'changeSPan2Color':
- var oSpan2 = document.querySelector('.span2');
- oSpan2.style.color = 'red';
- break;
- }
- });
- btn1.onclick = function () {
- parent.postMessage("GetWhiteLabel","*");
- }
- }
- </script>
- </body>
- </HTML>
- oframe.contentWindow.postMessage(data,origin,false); // 这个是 postMessage 的 API
- // 发送的数据 子文档地址 false
- // 在子文档中去监听那个 message 的变化
- Windows.addEventListener("message",function(res){
- console.log(res.data); // 这个东西就是发送过去的数据
- // 去根据传过来的不同的数据 再去做相应的判断
- })
- parent.postMessage('message',origin,false); // 同样也是类似的
- // 在父文档中去监听那个 message 的值
- Windows.addEventListener("message",function(res){
- console.log(res.data); // 这个东西就是发送过去的数据
- // 去根据传过来的不同的数据 再去做相应的判断
- });
来源: https://www.cnblogs.com/z937741304/p/9728160.html