❀ Bilibili 浮岚链接净化器

加载前清洁链接,移除跟踪参数。

当前为 2025-11-02 提交的版本,查看 最新版本

// ==UserScript==
// @name         ❀ Bilibili 浮岚链接净化器
// @namespace    https://bento.me/ranburiedbyacat
// @version      1.0.1
// @description  加载前清洁链接,移除跟踪参数。
// @author       嵐 @ranburiedbyacat
// @license      CC-BY-NC-SA-4.0
// @match        *://*.bilibili.com/*
// @compatible   Safari
// @compatible   Firefox
// @compatible   Chrome
// @icon         https://www.bilibili.com/favicon.ico
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    /**
     * ───────────────────────────────────────────────
     * ① 冗余参数列表
     * ───────────────────────────────────────────────
     * 功能:存储 B站 URL 中用于追踪、统计或营销的无关参数
     * 逻辑:统一收集参数,便于批量删除跟踪参数与陈睿鸡巴
     */
    const garbageParams = new Set([
    // ────────────── 来源跟踪 ──────────────
    'spm_id_from', 'from_source', 'sourceFrom', 'from_spmid', 'csource', 'vd_source', 'source','spm_id_from', 'from_source', 'sourceFrom', 'from_spmid', 'csource', 'vd_source', 'source', 'search_source',
    // ────────────── 分享参数 ───────────────
    'share_source', 'share_medium', 'share_plat', 'share_session_id', 'share_tag', 'share_from', 'plat_id',
    // ────────────── 广告统计 ──────────────
    'trackid', 'session_id', 'visit_id', 'unique_k', 'spmid', '-Arouter',
    // ────────────── 功能标记 ──────────────
    'msource', 'bsource', 'tab', 'is_story_h5', 'hotRank', 'launch_id', 'live_from'
]);

    /**
     * ───────────────────────────────────────────────
     * ② URL 解析工具
     * ───────────────────────────────────────────────
     * 功能:安全生成 URL 对象
     * 逻辑:处理相对路径或省略协议的 URL,解析失败返回 null
     */
    function parseURL(str) {
    try {
        if (typeof str === 'string' && str.includes('.') && !/^[a-z]+:/.test(str)) {
            str = str.startsWith("//") ? location.protocol + str : str;
        }
        return new URL(str, location.href);
    } catch (e) {
        return null;
    }
}

    /**
     * ───────────────────────────────────────────────
     * ③ URL 净化核心函数
     * ───────────────────────────────────────────────
     * 功能:删除 URL 中的追踪参数并标准化路径
     * 逻辑:
     *   - 仅处理 bilibili.com 域名
     *   - 将 bilibili.tv 替换为 www.bilibili.com
     *   - 删除垃圾参数
     *   - 去除路径尾部多余斜杠
     */
    function cleanUrl(urlStr) {
        const url = parseURL(urlStr);
        if (!url) return urlStr;

        if (!/bilibili\.com/.test(url.hostname)) return urlStr;
        if (url.hostname.includes('bilibili.tv')) url.hostname = 'www.bilibili.com';

        garbageParams.forEach(p => url.searchParams.delete(p));

        if (url.pathname.length > 1 && url.pathname.endsWith('/')) {
            url.pathname = url.pathname.slice(0, -1);
        }
        return url.toString();
    }

    /**
     * ───────────────────────────────────────────────
     * ④ 地址栏即时替换
     * ───────────────────────────────────────────────
     * 功能:页面加载前净化地址栏 URL
     * 逻辑:对比当前 URL,如不同则用 history.replaceState 更新
     */
    function replaceLocation(url) {
        if (url !== location.href) {
            history.replaceState(history.state, '', url);
        }
    }

    replaceLocation(cleanUrl(location.href));

    /**
     * ───────────────────────────────────────────────
     * ⑤ 链接点击拦截
     * ───────────────────────────────────────────────
     * 功能:在跳转前净化目标链接并移除追踪
     * 逻辑:根据点击类型决定当前页或新标签跳转,同时移除 ping
     */
    function handleClick(e) {
        const a = e.target.closest('a[href*="bilibili.com"]');
        if (!a) return;

        e.preventDefault();
        const clean = cleanUrl(a.href);

        if (a.target === '_blank' || e.ctrlKey || e.metaKey || e.shiftKey) {
            window.open(clean, '_blank');
        } else {
            location.href = clean;
        }
    }

    window.addEventListener('click', handleClick, true);
    window.addEventListener('contextmenu', handleClick, false);

    /**
     * ───────────────────────────────────────────────
     * ⑥ window.open 拦截
     * ───────────────────────────────────────────────
     * 功能:净化通过 JS 打开的新窗口 URL
     * 逻辑:调用原 window.open 前先净化 URL
     */
    const _open = window.open;
    window.open = (url, target, features) => _open.call(window, cleanUrl(url), target || '_blank', features);

    /**
     * ───────────────────────────────────────────────
     * ⑦ SPA 导航拦截
     * ───────────────────────────────────────────────
     * 功能:净化 pushState / replaceState 内部导航 URL
     * 逻辑:在调用原方法前先净化 URL
     */
    ['pushState', 'replaceState'].forEach(fn => {
        const orig = history[fn];
        history[fn] = (...args) => {
            if (typeof args[2] === 'string') {
                args[2] = cleanUrl(args[2]);
            }
            return orig.apply(history, args);
        };
    });

    /**
     * ───────────────────────────────────────────────
     * ⑧ Navigation API 拦截
     * ───────────────────────────────────────────────
     * 功能:净化 navigation.navigate() 导航 URL
     * 逻辑:拦截事件,替换目标 URL 并阻止默认导航
     */
    if (window.navigation) {
        window.navigation.addEventListener('navigate', e => {
            const newURL = cleanUrl(e.destination.url);
            if (newURL !== e.destination.url) {
                e.preventDefault();
                if (newURL !== location.href) {
                    history.replaceState(history.state, '', newURL);
                }
            }
        });
    }

    /**
     * ───────────────────────────────────────────────
     * ⑨ 动态节点净化
     * ───────────────────────────────────────────────
     * 功能:监测页面中新加入的 <a> 标签并即时净化
     * 逻辑:净化 href 并移除 ping 属性
     */
    const observer = new MutationObserver(muts => {
        for (let i = 0; i < muts.length; i++) {
            const m = muts[i];
            for (let j = 0; j < m.addedNodes.length; j++) {
                const node = m.addedNodes[j];
                if (node.nodeType !== 1) continue;
                const links = node.querySelectorAll ? node.querySelectorAll('a[href*="bilibili.com"]') : [];
                for (let k = 0; k < links.length; k++) {
                    const a = links[k];
                    a.href = cleanUrl(a.href);
                    a.removeAttribute('ping');
                }
            }
        }
    });
    observer.observe(document, { childList: true, subtree: true });

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址