// ==UserScript== // @name 极速去除链接重定向 // @author Meriel & 优化版 // @description 纯前端解析,无网络请求,跳转秒开 // @version 2.0.0 // @namespace Violentmonkey Scripts // @grant none // @match *://*/* // @run-at document-end // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/574775/%E6%9E%81%E9%80%9F%E5%8E%BB%E9%99%A4%E9%93%BE%E6%8E%A5%E9%87%8D%E5%AE%9A%E5%90%91.user.js // @updateURL https://update.greasyfork.icu/scripts/574775/%E6%9E%81%E9%80%9F%E5%8E%BB%E9%99%A4%E9%93%BE%E6%8E%A5%E9%87%8D%E5%AE%9A%E5%90%91.meta.js // ==/UserScript== (function () { 'use strict'; // 页面进入直接跳转类(秒跳) const jumpRules = [ { test: /coolapk\.com\/link\?.*url=/, get: u => new URL(u).searchParams.get('url') }, { test: /link\.csdn\.net\/\?.*target=/, get: u => new URL(u).searchParams.get('target') }, { test: /support\.qq\.com\/.*link-jump\?jump=/, get: u => new URL(u).searchParams.get('jump') }, { test: /mail\.qq\.com\/.*gourl=/, get: u => new URL(u).searchParams.get('gourl') }, { test: /yinxiang\.com\/OutboundRedirect\.action\?.*dest=/, get: u => new URL(u).searchParams.get('dest') }, { test: /youtube\.com\/redirect\?.*q=/, get: u => new URL(u).searchParams.get('q') }, { test: /developers\.weixin\.qq\.com\/.*href=/, get: u => new URL(u).searchParams.get('href') }, { test: /pc6\.com\/.*gourl=/, get: u => new URL(u).searchParams.get('gourl') }, { test: /blog\.51cto\.com\/transfer\?/, get: u => new URL(u).searchParams.get('url') }, { test: /c\.pc\.qq\.com.*pfurl=/, get: u => new URL(u).searchParams.get('pfurl') }, { test: /c\.pc\.qq\.com.*url=/, get: u => new URL(u).searchParams.get('url') }, { test: /\.urlshare\..+\/.*url=/, get: u => new URL(u).searchParams.get('url') }, { test: /docs\.qq\.com\/.*\?url=/, get: u => new URL(u).searchParams.get('url') }, { test: /kdocs\.cn\/office\/link\?.*target=/, get: u => new URL(u).searchParams.get('target') }, { test: /nodeseek\.com\/jump\?.*to=/, get: u => new URL(u).searchParams.get('to') }, { test: /wx\.mail\.qq\.com\/xmspamcheck\/xmsafejump\?/, get: u => new URL(u).searchParams.get('url') }, ]; // 进入页面就直接跳转,不等待任何加载 const current = location.href; for (const r of jumpRules) { if (r.test.test(current)) { try { const real = decodeURIComponent(r.get(current)); if (real && real.startsWith('http')) { location.replace(real); return; } } catch {} } } // 页面内链接替换(纯前端,无异步、无网络) const linkRules = [ { test: /link\.juejin\.(cn|im)\/\?target=/, get: u => new URL(u).searchParams.get('target') }, { test: /zhihu\.com\/\?target=/, get: u => new URL(u).searchParams.get('target') }, { test: /link\.zhihu\.com\/\?target=/, get: u => new URL(u).searchParams.get('target') }, { test: /douban\.com\/link2.*\?url=/, get: u => new URL(u).searchParams.get('url') }, { test: /sspai\.com\/link\?target=/, get: u => new URL(u).searchParams.get('target') }, { test: /gitee\.com\/link\?target=/, get: u => new URL(u).searchParams.get('target') }, { test: /infoq\.cn\/link\?target=/, get: u => new URL(u).searchParams.get('target') }, { test: /steamcommunity\.com\/linkfilter\/\?url=/, get: u => new URL(u).searchParams.get('url') }, { test: /weibo\.com\/sinaurl\?u=/, get: u => new URL(u).searchParams.get('u') }, { test: /afdian\.net\/link\?target=/, get: u => new URL(u).searchParams.get('target') }, { test: /oschina\.net\/action\/GoToLink\?url=/, get: u => new URL(u).searchParams.get('url') }, { test: /leetcode\.(cn|com)\/link\?target=/, get: u => new URL(u).searchParams.get('target') }, { test: /51\.ruyo\.net.*\?u=/, get: u => new URL(u).searchParams.get('u') }, { test: /bing\.com\/ck\/a\?/, get: u => null }, // 不处理,避免慢 { test: /baidu\.com\/link\?url=/, get: u => null }, // 不请求,只走前端 ]; const done = 'data-redirect-fixed'; function fixLink(a) { if (a[done]) return; a[done] = 1; const href = a.href; if (!href) return; for (const r of linkRules) { if (r.test.test(href)) { try { const real = r.get(href); if (real && real.startsWith('http')) { a.href = decodeURIComponent(real); } } catch {} break; } } } // 一次性批量处理 document.querySelectorAll('a').forEach(fixLink); // 极简监听新节点 const ob = new MutationObserver(ns => { for (const n of ns) { n.addedNodes.forEach(el => { if (el.tagName === 'A') fixLink(el); else el.querySelectorAll?.('a').forEach(fixLink); }); } }); ob.observe(document.body, { childList: true, subtree: true }); })();