上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
12下一页
返回列表 发新帖

获取iframe中元素,提示跨域访问出错

[复制链接]
  • TA的每日心情
    开心
    2022-8-28 08:36
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    1

    主题

    8

    回帖

    16

    积分

    助理工程师

    积分
    16

    新人报道

    发表于 2022-8-9 18:06:21 | 显示全部楼层 | 阅读模式
    悬赏10油猫币已解决

    站内王一之大佬写的解决跨域问题的两个方法,都看了,不知道具体怎么才能解决在iframe的页面上执行脚本,并返回页码数,目前的想法是设置全局变量n,在iframe界面运行脚本,改变变量n
    基本油猴编程的一些常见误区
    stackOverflow上有个相关回答,采用postMessage()进行跨域通信,实在搞不动怎么用到我这个脚本
    Blocked a frame with origin from accessing a cross-origin frame

    针对全国招投标公告打印不全,写了一个脚本,PDF的页数的ID = ‘numPages’,用document.getElementById('numPages')定位或者document.querySelector('#numpages'),元素都获取不到,提示Blocked a frame with origin from accessing a cross-origin frame,
    目前采用的是弹窗输入,解决页数的问题。但是发现很多页面都是有iframe,所以想搞清楚到底要怎样才能自由的获取iframe中的元素

    下面是需要脚本运行的示例界面
    https://ctbpsp.com/#/bulletinDetail?uuid=0f54093b-3869-4611-b2b5-71fd465e2670&inpvalue=2022%E5%B9%B4%E6%B9%96%E5%8D%97%E4%B8%AD%E7%83%9F%E7%A7%91%E7%A0%94%E8%AE%BE%E5%A4%87&dataSource=1

    // @name        调整打印文件
    // @namespace   print adjust
    // @match       https://ctbpsp.com/#/bulletinDetail?uuid=*
    // @match       https://bulletin.cebpubservice.com/qualifyBulletin/*
    // @match       https://bulletin.cebpubservice.com/biddingBulletin/*
    // @match       https://bulletin.cebpubservice.com/candidateBulletin/*
    // @match       https://bulletin.cebpubservice.com/resultBulletin/*
    // @run-at      document-end
    // @grant       unsafeWindow
    // @version     1.2.2
    // @author      我爱小熊啊
    // @description cebpubservice.com 文件加载时间较长,遇到未加载完成的,页码输入界面点击取消,文件加载完后,记住页码,刷新输入页码,等待加载完成
    // @description 将 ctbpsp.com 与 cebpubservice.com 的等待时间做区分
    // @description 自动隐藏 cebpubservice.com 上的二维码广告
    // @description 增加对 cebpubservice.com的支持
    // @description 中国招标投标公共服务平台公告文件打印调整
    // @description 2022/8/3 08:33:33
    // @license     MIT
    // ==/UserScript==
    
    // 设置延时定时器,避免网页未加载完,弹出页码输入框
    setTimeout(function(){
      var weburl = window.location.href;
      var n = 1;
      // ctbpsp.com 网页打印
      if(weburl.indexOf('ctbpsp.com')!=-1){
        // var windowAttribute = $('iframe');  ??? 引入 jQuery 库也不生效
        var windowAttribute = document.getElementsByTagName('iframe')[0];
        n = prompt('请输入文件页码','');
       if(n){    // 如果输入框点击取消,则 prompt 返回的是 null,则取消更改,否则网页会出错
         windowAttribute.width = 900;
         windowAttribute.height = 1150 * n;
         // alert("Hello");
       }
      }
    
      // cebpubservice.com 网页打印
      if(weburl.indexOf('cebpubservice.com')!=-1){
        setTimeout(function(){
          var p = document.getElementsByClassName('pdf_wraper')[0];
          var b = document.getElementsByClassName('PublicAddress')[0];
          b.style.display = 'none';
          // var n = prompt('请输入文件页码','');
          n = prompt('请输入文件页码','');
          if(n){
            p.style.width = '900px';
            var h = n * 1150;
            var gaodu = h + 'px';
            p.style.height = gaodu;
          }
        }, 6000);
      }
    }, 3000);

    最佳答案

    查看完整内容

    iframe内部可以理解为另一个网页,如果网页跨域,那无论如何也是不能直接操作其中的元素的。跨域页面可以通过postMessage互相发送数据,根据数据在对应环境中执行对应操作,这需要双方的配合。比如A可以给B发送一个指令showMessage,B接收到以后展示相应元素,但A不能直接操作B内的元素。全局变量是没用的,代码虽然看起来在同一个脚本,但实际运行在不同的环境中。下面是实现你需求的一个示例: ...
  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    881

    回帖

    1379

    积分

    荣誉开发者

    积分
    1379

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-8-9 18:06:22 | 显示全部楼层
    iframe内部可以理解为另一个网页,如果网页跨域,那无论如何也是不能直接操作其中的元素的。跨域页面可以通过postMessage互相发送数据,根据数据在对应环境中执行对应操作,这需要双方的配合。比如A可以给B发送一个指令showMessage,B接收到以后展示相应元素,但A不能直接操作B内的元素。全局变量是没用的,代码虽然看起来在同一个脚本,但实际运行在不同的环境中。下面是实现你需求的一个示例:
    1. // ==UserScript==
    2. // @name         跨域交互
    3. // @description  ...
    4. // @namespace    ...
    5. // @author       ...
    6. // @version      1.0
    7. // @match        https://ctbpsp.com/*
    8. // @match        https://custominfo.cebpubservice.com/*
    9. // @grant        none
    10. // @run-at       document-idle
    11. // ==/UserScript==

    12. (function() {
    13.     'use strict';
    14.     // 主页面
    15.     if (location.hostname === 'ctbpsp.com') {
    16.         // 监听message事件,取得页码数后调整iframe大小
    17.         window.addEventListener('message', e => {
    18.             if ('numPages' in e.data) {
    19.                 const iframe = document.querySelector('.pdf-viewer');
    20.                 iframe.width = 900;
    21.                 iframe.height = 1150 * e.data.numPages;
    22.             }
    23.         });
    24.     }
    25.     // iframe页面
    26.     if (location.hostname === 'custominfo.cebpubservice.com') {
    27.         // iframe内有一个全局对象PDFViewerApplication,可对其进行劫持来判断pdf加载完毕,也可以用其他方法。
    28.         const _load = window.PDFViewerApplication.load;
    29.         window.PDFViewerApplication.load = function(pdfDocument) {
    30.             // 获取页码数,发送给主页面
    31.             window.top.postMessage({
    32.                 numPages: pdfDocument._pdfInfo.numPages
    33.             }, 'https://ctbpsp.com');
    34.             return _load.call(this, pdfDocument);
    35.         };
    36.     }
    37. })();
    复制代码
    已有1人评分好评 贡献 理由
    王一之 + 1 + 1 赞一个!

    查看全部评分 总评分:好评 +1  贡献 +1 

    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-8-28 08:36
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    1

    主题

    8

    回帖

    16

    积分

    助理工程师

    积分
    16

    新人报道

    发表于 2022-8-9 18:17:37 | 显示全部楼层
    如有哪位大佬能帮我解决这个问题,悬赏20元人民币,QQ:1664307236
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5965

    回帖

    6763

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6763

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-8-9 19:43:05 | 显示全部楼层
    iframe子对父通信使用postmessage思路是对的
    可以参考
    https://bbs.tampermonkey.net.cn/ ... thread&tid=2267
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5965

    回帖

    6763

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6763

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-8-9 19:44:34 | 显示全部楼层
    还有一个思路就是使用
    GM_addValueChangeListener
    GM_removeValueChangeListener
    GM_setValue
    三个api组合
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情

    前天 16:31
  • 签到天数: 309 天

    [LV.8]以坛为家I

    12

    主题

    63

    回帖

    642

    积分

    荣誉开发者

    积分
    642

    荣誉开发者生态建设者

    发表于 2022-8-9 19:50:21 | 显示全部楼层

    这还是一个关于iframe的异步获取元素的问题,我之前谈过waitForKeyElements这个库遇到的跨域问题,你和我遇到过的问题很像。
    cxxjackie专门写了一个库ElementGetter来解决此类问题,我估计cxxjackie大佬看到后会来推广他的ElementGetter。
    我先给出使用waitForKeyElements的方法,抛砖引玉。

    1.头部没有匹配iframe的网址,需要匹配:

    // @match       https://custominfo.cebpubservice.com/*
    // @require      https://z.chaoxing.com/js/jquery-3.5.0.min.js
    // @require      https://greasyfork.org/scripts/383527-wait-for-key-elements/code/Wait_for_key_elements.js?version=701631
    // @grant        none

    2.使用waitForKeyElements获取numPages的代码:

    waitForKeyElements ("span#numPages.toolbarLabel",(jNode)=>{
        console.log(jNode[0]); //输出 <span id=​"numPages" class=​"toolbarLabel">​/ 4​</span>​
        console.log('fuck you')
    },'iframe.pdf-viewer');

    3.相关帖子

    当冥想的日子飞逝,喧嚣的日子把我们唤去,且在此地留下些微的痕迹
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    881

    回帖

    1379

    积分

    荣誉开发者

    积分
    1379

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-8-9 21:37:54 | 显示全部楼层
    朱焱伟 发表于 2022-8-9 19:50
    [md]这还是一个关于iframe的异步获取元素的问题,我之前谈过waitForKeyElements这个库遇到的跨域问题,你和 ...

    这其实不是获取元素的问题,跨iframe≠跨域。waitForKeyElements只能获取同源iframe内的元素,ElementGetter也不能解决跨域。
    回复

    使用道具 举报

  • TA的每日心情

    前天 16:31
  • 签到天数: 309 天

    [LV.8]以坛为家I

    12

    主题

    63

    回帖

    642

    积分

    荣誉开发者

    积分
    642

    荣誉开发者生态建设者

    发表于 2022-8-9 22:00:58 | 显示全部楼层
    本帖最后由 朱焱伟 于 2022-8-9 22:12 编辑
    cxxjackie 发表于 2022-8-9 21:37
    这其实不是获取元素的问题,跨iframe≠跨域。waitForKeyElements只能获取同源iframe内的元素,ElementGet ...

    看到最新评论的代码了,老铁666
    当冥想的日子飞逝,喧嚣的日子把我们唤去,且在此地留下些微的痕迹
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-8-28 08:36
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    1

    主题

    8

    回帖

    16

    积分

    助理工程师

    积分
    16

    新人报道

    发表于 2022-8-10 08:04:31 | 显示全部楼层
    cxxjackie 发表于 2022-8-9 21:46
    iframe内部可以理解为另一个网页,如果网页跨域,那无论如何也是不能直接操作其中的元素的。跨域页面可以通 ...

    感谢大佬指点,作为一个小白,太感谢了,确实解决了我的困扰,之前悬赏的20元,看怎么给方便点,请大佬喝杯咖啡
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-8-28 08:36
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    1

    主题

    8

    回帖

    16

    积分

    助理工程师

    积分
    16

    新人报道

    发表于 2022-8-10 08:05:52 | 显示全部楼层
    李恒道 发表于 2022-8-9 19:44
    还有一个思路就是使用
    GM_addValueChangeListener
    GM_removeValueChangeListener

    感谢大佬回复,之前就是在论坛看你的帖子,写的第一个脚本,虽然很简单,但是对我而言,解决了工作中的一个问题,也是很有成就感了
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表