神奇的Willem

微信QQ内置浏览器拦截功能

拦截与防红的区别

这不是一个真真的防红,如果你已经红了去申请即可,不做介绍。

遵纪守法,请勿干坏事哦!

  1. 真正的“防红” (Problem A):

    • 问题: 你的域名(比如 example.com)因为内容违规或被恶意举报,被腾讯的服务器拉黑了。

    • 表现: 用户在微信里点击你的链接,根本看不到你的网站,而是直接看到一个红色的、全屏的腾讯警告页面,提示“已停止访问该网页”。(从DNS查询域名时候就被拦截不让访问)

    • 我们的代码: 无效! 因为用户的访问请求在到达你的服务器之前,就被腾讯的网关给拦截了。你的网站代码(包括我们写的JS)根本没有机会运行。

    • 解决: 这种问题只能通过服务器申诉、换域名、或使用“防红短网址”等技术来解决。(Github有项目)

  2. 我们的“引导跳出” (Problem B):

    • 问题: 你的域名是干净的、可以正常访问的。但是,你不希望用户在微信/QQ的内置浏览器里浏览你的博客。

    • 为什么不希望?

      • 体验差: 内置浏览器功能残缺,很多网页特效(CSS)和高级功能(JS)不支持。

      • 功能受限: 比如无法下载文件、无法调起支付、复制粘贴不方便等。

      • 容易被误判: 内置浏览器的安全检测很“傻”,有时你博客里的一些正常功能(比如登录、分享)可能会被它误判为“诱导分享”或“钓鱼”,导致你的域名未来被“防红”(变成Problem A)。

源码展示

<script>
document.addEventListener("DOMContentLoaded", function() {
    var ua = navigator.userAgent.toLowerCase();
    var isWeChat = ua.indexOf('micromessenger') > -1;
    var isQQ = ua.indexOf('qq') > -1 && ua.indexOf('mqqbrowser') === -1;

    if (isWeChat || isQQ) {
        // 1. CSS 样式:全屏、黑白、居中、高级感
        var styleText = `
            /* 遮罩层本体:完全覆盖,不透明 */
            .browser-overlay {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: #000; /* 纯黑背景,完全不透明 */
                z-index: 99999;
                
                /* 使用 Flexbox 实现内容垂直和水平居中 */
                display: flex;
                flex-direction: column; /* 垂直排列子元素 */
                justify-content: center; /* 垂直居中 */
                align-items: center; /* 水平居中 */
                text-align: center;
                padding: 20px; /* 内边距 */
                box-sizing: border-box; /* 确保 padding 不会撑大元素 */
            }

            /* 拦截图片样式 */
            .browser-overlay-image {
                max-width: 80%; /* 图片最大宽度,避免过大 */
                max-height: 50vh; /* 图片最大高度,占用视口高度的50% */
                object-fit: contain; /* 保持图片比例,完整显示 */
                margin-bottom: 25px; /* 图片下方与文字的间距 */
            }

            /* 提示文字样式 */
            .browser-overlay-text {
                color: #fff; /* 白色文字 */
                font-size: 17px;
                line-height: 1.6;
                margin-bottom: 25px; /* 文字下方与按钮的间距 */
                user-select: none; /* 禁止选择文字 */
            }

            /* --- 新增:标题样式 --- */
            .browser-overlay-title {
                font-size: 24px; /* 略大一点的字体 */
                font-weight: bold; /* 加粗 */
                color: #fff;
                margin-bottom: 15px; /* 和下面文字的间距 */
            }
            /* --- 新增结束 --- */

            /* 复制按钮样式 */
            .browser-overlay-button {
                background: #fff; /* 白色背景 */
                color: #000; /* 黑色文字 */
                border: none;
                padding: 12px 30px;
                font-size: 16px;
                font-weight: bold;
                border-radius: 5px; /* 圆角 */
                cursor: pointer;
                transition: background 0.3s ease; /* 鼠标悬停动画 */
                user-select: none; /* 禁止选择按钮文字 */
            }

            .browser-overlay-button:active {
                background: #eee; /* 点击时的背景色 */
            }

            /* 复制成功提示 */
            .copy-success-tip {
                color: #fff;
                font-size: 14px;
                margin-top: 10px;
                opacity: 0;
                transition: opacity 0.3s ease-out;
            }
            .copy-success-tip.show {
                opacity: 1;
            }
        `;

        // 2. 创建 <style> 标签并注入
        var style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML = styleText;
        document.head.appendChild(style);

        // 3. 创建遮罩层 <div> 并注入内容
        var div = document.createElement('div');
        div.className = 'browser-overlay';
        // --- HTML 结构更新 ---
        div.innerHTML = `
            <img src="https://你的图片链接.png" alt="请在浏览器打开" class="browser-overlay-image">
            <div class="browser-overlay-text">
                <p class="browser-overlay-title">拦截成功</p>
                <p>检测到您正在使用微信或QQ内置浏览器,</p>
                <p>请复制网址,并在外部浏览器中打开。</p>
            </div>
            <button class="browser-overlay-button" id="copyUrlButton">复制链接</button>
            <div class="copy-success-tip" id="copySuccessTip">复制成功!</div>
        `;
        document.body.appendChild(div);

        // 4. (可选) 禁止背景页面滚动
        document.body.style.overflow = 'hidden';

        // 5. 添加复制链接功能
        var copyButton = document.getElementById('copyUrlButton');
        var successTip = document.getElementById('copySuccessTip');
        copyButton.addEventListener('click', function() {
            var currentUrl = window.location.href; // 获取当前页面的URL

            // 创建一个临时的textarea元素来复制文本
            var tempInput = document.createElement('textarea');
            tempInput.value = currentUrl;
            document.body.appendChild(tempInput);
            tempInput.select(); // 选中文本
            document.execCommand('copy'); // 执行复制命令
            document.body.removeChild(tempInput); // 移除临时元素

            // 显示复制成功提示
            successTip.classList.add('show');
            setTimeout(function() {
                successTip.classList.remove('show');
            }, 2000); // 2秒后隐藏
        });
    }
});
</script>

思路分析和结局方法

1.只要用户不举报我们的网站或在内部举报我们的网站,就不会封。

2.我们的网站不能有名感信息,如果看到了程序会扫描或者有人举报等。

3.访问次数不能过多如在页面频烦访问转跳请求等。

思路:只要引导用户不在内部浏览器打开或者举报就可以。并遮蔽内容强制用户复制跳转。

解决办法:

当一个访客打开你的网页时,浏览器会发送一个“身份证”,叫做 User Agent (UA)。(之前介绍过)

  • 普通电脑 Chrome 浏览器的 UA 可能长这样: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/100.0(我是mac)

  • 微信内置浏览器的 UA 必定会包含一个特殊的词: ... MicroMessenger/8.0.0 ...

  • QQ内置浏览器的 UA 必定会包含一个词: ... QQ/8.8.8 ...

我们的代码第一步就是读取这个UA: var ua = navigator.userAgent.toLowerCase(); var isWeChat = ua.indexOf('micromessenger') > -1; var isQQ = ua.indexOf('qq') > -1;

这三行代码的意思是:“检查访客的‘身份证’(UA),如果里面有 micromessengerqq 字样,就把他标记为‘来自微信/QQ’”。

我们一步步分析哈不要着急

变量定义判断特殊字符

document.addEventListener("DOMContentLoaded", function() {
    var ua = navigator.userAgent.toLowerCase();
    var isWeChat = ua.indexOf('micromessenger') > -1;
    var isQQ = ua.indexOf('qq') > -1 && ua.indexOf('mqqbrowser') === -1;

接下来是一个 if 语句: if (isWeChat || isQQ) { ... }

意思是:发现这个人被标记为‘来自微信/QQ’,那么就执行大括号 {...} 里的所有操作。”

如果触发了拦截,代码会立刻执行以下操作,这一切都发生在访客的手机上,是动态生成的如果没检测就不加载遮蔽罩:

  1. 创建 <style> 标签:

    • 代码在内存中创建了一个 <style> 标签。

    • 它把我们写好的所有 CSS 样式(如 background: #000;position: fixed;width: 100%;height: 100%;z-index: 99999; 等)全部塞进这个标签里。

    • position: fixedz-index: 99999 是最关键的,它们的意思是“创建一个固定在屏幕上、且层级在最顶层(99999)的图层”。

    • 最后,把这个 style 标签插入到网页的 <head> 中,让样式生效。

动态生成可以防止不同设备尺寸不一样,直接最大覆盖。

冻结页面:

  • document.body.style.overflow = 'hidden';

不可以上下滚动。也不许点击。

总结与使用

根据上述代码,修改注释要求更换照片,文字内容。复制放在页脚即可。

不建议放在头,因为头还有别的用处,头在请求时候是最先开始,此时我写的body内容css文件没有加载,可能照片会出不来,甚至无法出发拦截界面遮蔽罩就被停止了。我们可以放在页脚,等待页面都加载完毕自动就拦截了,也防止串改头。