真正的“防红” (Problem A):
问题: 你的域名(比如 example.com)因为内容违规或被恶意举报,被腾讯的服务器拉黑了。
表现: 用户在微信里点击你的链接,根本看不到你的网站,而是直接看到一个红色的、全屏的腾讯警告页面,提示“已停止访问该网页”。(从DNS查询域名时候就被拦截不让访问)
我们的代码: 无效! 因为用户的访问请求在到达你的服务器之前,就被腾讯的网关给拦截了。你的网站代码(包括我们写的JS)根本没有机会运行。
解决: 这种问题只能通过服务器申诉、换域名、或使用“防红短网址”等技术来解决。(Github有项目)
我们的“引导跳出” (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),如果里面有 micromessenger 或 qq 字样,就把他标记为‘来自微信/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’,那么就执行大括号 {...} 里的所有操作。”
如果触发了拦截,代码会立刻执行以下操作,这一切都发生在访客的手机上,是动态生成的如果没检测就不加载遮蔽罩:
创建 <style> 标签:
代码在内存中创建了一个 <style> 标签。
它把我们写好的所有 CSS 样式(如 background: #000;、position: fixed;、width: 100%;、height: 100%;、z-index: 99999; 等)全部塞进这个标签里。
position: fixed 和 z-index: 99999 是最关键的,它们的意思是“创建一个固定在屏幕上、且层级在最顶层(99999)的图层”。
最后,把这个 style 标签插入到网页的 <head> 中,让样式生效。
动态生成可以防止不同设备尺寸不一样,直接最大覆盖。
冻结页面:
document.body.style.overflow = 'hidden';
不可以上下滚动。也不许点击。
根据上述代码,修改注释要求更换照片,文字内容。复制放在页脚即可。
不建议放在头,因为头还有别的用处,头在请求时候是最先开始,此时我写的body内容css文件没有加载,可能照片会出不来,甚至无法出发拦截界面遮蔽罩就被停止了。我们可以放在页脚,等待页面都加载完毕自动就拦截了,也防止串改头。