恢复网站console.log的脚本

第一种:

javascript 复制代码
  // 恢复被网站禁用的 console 方法
  (function() {
    const iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
    const nativeConsole = iframe.contentWindow.console;

    ['log', 'warn', 'error', 'info', 'debug', 'dir', 'table', 'trace',
     'group', 'groupEnd', 'groupCollapsed', 'clear', 'count', 'assert',
     'time', 'timeEnd', 'timeLog'].forEach(method => {
      if (nativeConsole[method]) {
        console[method] = nativeConsole[method].bind(nativeConsole);
      }
    });

    document.body.removeChild(iframe);
    console.log('Console 方法已恢复!');
  })();

第二种:

javascript 复制代码
  // 恢复被 aes.util.js 禁用的 console 方法
  (function() {
    var iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
    var nc = iframe.contentWindow.console;

    // 直接替换整个 window.console
    try {
      Object.defineProperty(window, 'console', {
        value: {
          log: nc.log.bind(nc),
          warn: nc.warn.bind(nc),
          error: nc.error.bind(nc),
          info: nc.info.bind(nc),
          debug: nc.debug.bind(nc),
          dir: nc.dir.bind(nc),
          table: nc.table.bind(nc),
          trace: nc.trace.bind(nc),
          group: nc.group.bind(nc),
          groupEnd: nc.groupEnd.bind(nc),
          clear: nc.clear.bind(nc),
          count: nc.count.bind(nc),
          assert: nc.assert.bind(nc),
          time: nc.time.bind(nc),
          timeEnd: nc.timeEnd.bind(nc)
        },
        writable: false,
        configurable: false
      });
      console.log('%c Console 已恢复!', 'color: green; font-weight: bold;');
    } catch(e) {
      console.error('恢复失败:', e);
    }

    document.body.removeChild(iframe);
  })();

第三种:

javascript 复制代码
  // 备用方案:直接使用 iframe 的 console
  (function() {
    var iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    iframe.id = 'console-restore-iframe';
    document.body.appendChild(iframe);

    // 将 iframe 的 console 暴露为全局变量
    window.c = iframe.contentWindow.console;

    console.log = window.c.log.bind(window.c);
    console.warn = window.c.warn.bind(window.c);
    console.error = window.c.error.bind(window.c);
    console.info = window.c.info.bind(window.c);

    window.c.log('%c 使用 window.c.log() 或 console.log() 打印日志', 'color: green');
  })();

第四种:

javascript 复制代码
  /**
   * 恢复被网站禁用的 console 方法
   * 兼容各种反调试场景:简单重写、Object.defineProperty 锁定、持续监控重写等
   */
  (function restoreConsole() {
    // 创建隐藏的 iframe 获取原生 console
    var iframe = document.createElement('iframe');
    iframe.style.cssText = 'display:none!important;width:0;height:0;border:0;';
    iframe.id = '__console_restore_iframe__';

    // 移除可能存在的旧 iframe
    var oldIframe = document.getElementById('__console_restore_iframe__');
    if (oldIframe) oldIframe.remove();

    document.body.appendChild(iframe);
    var nativeConsole = iframe.contentWindow.console;

    // 要恢复的方法列表
    var methods = ['log', 'warn', 'error', 'info', 'debug', 'dir', 'table',
                   'trace', 'group', 'groupEnd', 'groupCollapsed', 'clear',
                   'count', 'assert', 'time', 'timeEnd', 'timeLog'];

    // 构建新的 console 对象
    var newConsole = {};
    methods.forEach(function(method) {
      if (nativeConsole[method]) {
        newConsole[method] = nativeConsole[method].bind(nativeConsole);
      }
    });

    // 尝试方式二:替换整个 window.console
    try {
      Object.defineProperty(window, 'console', {
        value: newConsole,
        writable: false,
        configurable: false
      });
    } catch(e) {
      // 方式二失败,尝试方式一:逐个替换方法
      methods.forEach(function(method) {
        try {
          Object.defineProperty(console, method, {
            value: newConsole[method],
            writable: false,
            configurable: false
          });
        } catch(e2) {
          // Object.defineProperty 失败,直接赋值
          try {
            console[method] = newConsole[method];
          } catch(e3) {}
        }
      });
    }

    // 暴露备用接口 window.c(方式三的保底方案)
    window.c = nativeConsole;

    // 注意:不删除 iframe,保持 nativeConsole 存活
    // 如果介意 DOM 中有隐藏 iframe,可以取消下面的注释,但可能导致某些情况失效
    // document.body.removeChild(iframe);

    // 验证并提示
    console.log('%c[Console Restored] ', 'color:#0a0;font-weight:bold',
                'console 已恢复! 备用方案: window.c.log()');
  })();

第五种,简化版(日常使用)覆盖了 99% 的场景,记住这一个就够了

javascript 复制代码
  // 万能恢复 console 脚本
  (function(){
    var f = document.createElement('iframe');
    f.style.display = 'none';
    document.body.appendChild(f);
    var nc = f.contentWindow.console;

    ['log','warn','error','info','debug'].forEach(function(m){
      try { console[m] = nc[m].bind(nc); } catch(e){}
    });

    window.c = nc; // 保底方案
    console.log('Console 已恢复! 备用: window.c.log()');
  })();

油猴脚本:

javascript 复制代码
  // ==UserScript==
  // @name         恢复 Console (防重写版)
  // @namespace    http://tampermonkey.net/
  // @version      2.0
  // @description  恢复被网站禁用的 console.log,并防止被再次重写
  // @match        https://www.birdreport.cn/*
  // @run-at       document-start
  // @grant        none
  // ==/UserScript==

  (function() {
    // 保存原生 console 引用
    var nativeConsole = console;

    // 创建 iframe 获取干净的 console
    var getCleanConsole = function() {
      var f = document.createElement('iframe');
      f.style.display = 'none';
      (document.body || document.documentElement).appendChild(f);
      var c = f.contentWindow.console;
      return c;
    };

    // 页面加载完成后执行保护
    var protect = function() {
      var nc = getCleanConsole();

      // 创建不可修改的 console 对象
      var protectedConsole = {};
      ['log','warn','error','info','debug','dir','table','trace','group','groupEnd','clear','count','assert','time','timeEnd'].forEach(function(m) {
        if (nc[m]) {
          Object.defineProperty(protectedConsole, m, {
            value: nc[m].bind(nc),
            writable: false,
            configurable: false
          });
        }
      });

      // 锁定 window.console
      try {
        Object.defineProperty(window, 'console', {
          value: protectedConsole,
          writable: false,
          configurable: false
        });
      } catch(e) {
        // 备用方案
        window.c = nc;
      }

      // 同时暴露 window.c 作为保底
      window.c = nc;

      console.log('%c[Console Protected]', 'color:green;font-weight:bold', 'console 已恢复并锁定!');
    };

    // DOM 准备好后执行
    if (document.body) {
      protect();
    } else {
      document.addEventListener('DOMContentLoaded', protect);
    }

    // 延迟再执行一次,确保在网站脚本之后
    setTimeout(protect, 1000);
    setTimeout(protect, 3000);
  })();
相关推荐
亿元程序员7 小时前
太牛了!这AI做出来的游戏,居然还能变现!
前端
hellice7 小时前
闪传 FlashDrop 实战:我用 300 行 Node 代码做了个「4 位取件码」临时文件中转站
前端·产品
用户0829773260057 小时前
RTX 5500 MIG 踩坑记录:切分之后模型跑不起来,排错整整一下午
前端
Lank_M7 小时前
AI 放大后的图更清楚,但它不能当原图入库
前端
Swot7 小时前
SvelteKit 数据流研究:`+page.js` 和 `+page.server.js` 到底谁在跑,数据又去了哪儿
前端·后端
用户4147679304157 小时前
Windows 触摸屏上 Swiper 轮播滑不动?可能是内部滚动容器抢走了你的手势
前端
张明君644517 小时前
从一个 Referer 引发的 403,到 SSR 服务失稳:Astro 流式渲染与缓存失效分析
前端
律宏阔7 小时前
微信小程序 + Taro + TDesign 去掉 [&&&],让普通 Tailwind 类接管局部样式
前端·微信小程序·taro
费曼学习法7 小时前
把 3 个内部服务封装成 MCP Server 的工程复盘:进程模型、超时与错误契约
前端
ruanno_top7 小时前
给标签页加 roving tabindex,整组反而键盘进不去了
vue.js