Greasy Fork is available in English.
静默扫描页面链接,预先缓存检测结果,点击瞬发警告
当前为
// ==UserScript==
// @name anti-rickroll
// @namespace http://tampermonkey.net/
// @version 2.0
// @description 静默扫描页面链接,预先缓存检测结果,点击瞬发警告
// @author dext
// @match *://*/*
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @connect anti-rickroll.dext.top
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
const API_ENDPOINT = "https://anti-rickroll.dext.top";
const cache = new Map(); // 缓存:URL -> isRickroll (true/false)
const scanning = new Set(); // 正在扫描中的URL,避免重复请求
// 极简弹窗样式
GM_addStyle(`
#rick-guard-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 2147483647; display: flex; justify-content: center; align-items: center; backdrop-filter: blur(5px); }
.rick-modal { background: #fff; padding: 30px; border-radius: 12px; width: 320px; text-align: center; font-family: sans-serif; }
.rick-btns { display: flex; gap: 10px; margin-top: 20px; }
.rick-btn { flex: 1; padding: 10px; border-radius: 6px; cursor: pointer; border: none; font-weight: bold; }
.btn-go { background: #ff4444; color: white; }
.btn-cancel { background: #f0f0f0; }
`);
// 核心:扫描页面上的链接
function scanLinks() {
const links = Array.from(document.querySelectorAll('a[href]'));
links.forEach(a => {
const url = a.href;
// 过滤掉非http、锚点、已处理过的
if (!url.startsWith('http') || cache.has(url) || scanning.has(url)) return;
// 过滤常见的大型信任网站,减少 API 压力
const domain = new URL(url).hostname;
if (domain.includes('google.com') || domain.includes('baidu.com') || domain.includes('github.com')) {
cache.set(url, false);
return;
}
scanning.add(url);
GM_xmlhttpRequest({
method: "POST",
url: API_ENDPOINT,
headers: { "Content-Type": "application/json" },
data: JSON.stringify({ url: url }),
onload: function(res) {
try {
const data = JSON.parse(res.responseText);
cache.set(url, data.isRickroll);
// 如果确定是诈骗,可以给链接加个淡淡的红边提醒(可选)
// if(data.isRickroll) a.style.outline = "1px dashed rgba(255,0,0,0.5)";
} catch (e) {}
scanning.delete(url);
},
onerror: () => scanning.delete(url)
});
});
}
// 初始扫描
setTimeout(scanLinks, 1000);
// 监听动态加载的内容(如瀑布流)
const observer = new MutationObserver(scanLinks);
observer.observe(document.body, { childList: true, subtree: true });
// 点击拦截逻辑
window.addEventListener('click', function(e) {
const a = e.target.closest('a');
if (!a || !a.href) return;
const isRick = cache.get(a.href);
// 如果缓存里确认是 Rickroll
if (isRick === true) {
e.preventDefault();
e.stopPropagation();
showWarning(a.href, a);
return;
}
// 如果还没检测完 (isRick 为 undefined),则放行,或者你可以选择拦截等待
// 这里选择直接放行以保证用户体验,因为大部分链接是安全的
}, true);
function showWarning(url, originalElement) {
const overlay = document.createElement('div');
overlay.id = 'rick-guard-overlay';
overlay.innerHTML = `
<div class="rick-modal">
<h2 style="color:#ff4444;margin:0">诈骗链接警告</h2>
<p style="color:#666">该链接经 AI 识别为 Rickroll 或钓鱼网页,是否继续访问?</p>
<div class="rick-btns">
<button class="rick-btn btn-cancel" id="r-close">取消</button>
<button class="rick-btn btn-go" id="r-go">继续访问</button>
</div>
</div>
`;
document.body.appendChild(overlay);
document.getElementById('r-close').onclick = () => overlay.remove();
document.getElementById('r-go').onclick = () => {
overlay.remove();
cache.set(url, false); // 暂时标记为安全以允许跳转
window.location.href = url;
};
}
})();