Greasy Fork

Greasy Fork is available in English.

极速去除链接重定向

纯前端解析,无网络请求,跳转秒开

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name              极速去除链接重定向
// @author            Meriel & 优化版
// @description       纯前端解析,无网络请求,跳转秒开
// @version           2.0.0
// @namespace         Violentmonkey Scripts
// @grant             none
// @match             *://*/*
// @run-at            document-end
// @license           MIT
// ==/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 });

})();