M3U8 Video Detector and Downloader

Automatically detect the m3u8 video of the page and download it completely. Once detected the m3u8 link, it will appear in the upper right corner of the page. Click download to jump to the m3u8 downloader.

< Feedback on M3U8 Video Detector and Downloader

Review: OK - script works, but has bugs

§
Posted: 2025-07-13
Edited: 2025-07-13

在qq邮箱界面会导致网页无限刷新,一直进不去。确认了是你的脚本所产生的问题。 这个用户脚本在 https://wx.mail.qq.com 中导致无限刷新的问题,可能与以下几个原因有关:


1. MutationObserver 监听导致循环触发

脚本中的 watchBodyChange 函数使用了 MutationObserver 监听 DOM 变化,而 QQ 邮箱的页面可能频繁更新 DOM 结构(例如动态加载内容或实时刷新)。当脚本检测到变化时,会触发 work() 函数,而 work() 可能会修改 DOM(例如插入播放按钮),从而再次触发 MutationObserver,形成无限循环。

关键代码:

function watchBodyChange(onchange) {
    let timeout;
    let observer = new MutationObserver(() => {
        if (!timeout) {
            timeout = setTimeout(() => {
                timeout = null;
                onchange(); // 触发 work()
            }, 200);
        }
    });
    observer.observe(document.documentElement, {
        childList: true,
        subtree: true, // 监听整个 DOM 树
        attributes: true,
        characterData: true
    });
}

问题点:

  • subtree: true 会监听所有子节点的变化,包括 QQ 邮箱内部动态更新的部分(如邮件列表、未读标记等)。
  • work() 中插入的按钮可能被 QQ 邮箱的脚本认为是“非法”修改,导致页面尝试修复或刷新。

2. XMLHttpRequestfetch 的劫持

脚本重写了 XMLHttpRequest.prototype.openResponse.prototype.text,可能会干扰 QQ 邮箱的正常网络请求逻辑。如果 QQ 邮箱依赖这些 API 的原始行为(例如校验请求或响应),劫持后的逻辑可能导致请求失败,触发页面刷新。

关键代码:

unsafeWindow.XMLHttpRequest.prototype.open = function (...args) {
    this.addEventListener("load", () => {
        try {
            let content = this.responseText;
            if (checkContent(content)) doM3U({ url: args[1], content });
        } catch { }
    });
    return _open.apply(this, args);
}

问题点:

  • QQ 邮箱可能依赖 XMLHttpRequestfetch 的原始行为,劫持后可能导致请求异常。

3. 全局事件监听冲突

脚本监听了全局的 clickmouse 事件,并调用了 e.preventDefault()e.stopPropagation()。如果 QQ 邮箱依赖这些事件的冒泡或默认行为(例如按钮点击跳转),可能会导致页面功能异常,间接引发刷新。

关键代码:

window.addEventListener("click", onEvents, true); // 捕获阶段监听
function onEvents(e) {
    if (e.target.hasAttribute('data-wtmzjk-mag-url')) {
        e.preventDefault();
        e.stopPropagation();
        // ...
    }
}

4. CSS 注入干扰

脚本通过 addStyle 动态注入 CSS 规则,而 QQ 邮箱可能有严格的样式校验机制。如果注入的 CSS 包含非法属性(如控制台报错的 -moz-osx-font-smoothing-ms-input-placeholder),可能会导致页面尝试修复样式,引发刷新。


解决方案

  1. 排除 QQ 邮箱域名 在脚本的 @exclude 中添加 QQ 邮箱的域名,避免脚本在该页面运行:

    // @exclude *://wx.mail.qq.com/*
    
  2. 优化 MutationObserver 限制 MutationObserver 的监听范围或频率,避免频繁触发:

    observer.observe(document.body, {
       childList: true,
       subtree: false, // 仅监听直接子节点
       attributes: false
    });
    
  3. 避免劫持关键 API 在特定域名下禁用对 XMLHttpRequestfetch 的劫持:

    if (!location.host.includes('mail.qq.com')) {
       unsafeWindow.XMLHttpRequest.prototype.open = ...;
    }
    
  4. 修复 CSS 注入 移除非标准的 CSS 属性或伪类,避免控制台报错。


总结

最可能的原因是 MutationObserver 和 QQ 邮箱的动态 DOM 更新形成了无限循环,其次是全局事件监听或 API 劫持干扰了页面正常逻辑。通过排除域名或优化监听逻辑可以解决问题。

§
Posted: 2025-07-13

目前是将qq邮箱排除后规避这个问题:
// @exclude *://wx.mail.qq.com/*

Post reply

Sign in to post a reply.