spm_Track_Block_Tool

移除链接中的spm跟踪参数

目前為 2022-04-10 提交的版本,檢視 最新版本

// ==UserScript==
// @name         spm_Track_Block_Tool
// @namespace    _s7util__
// @version      0.5.4
// @description:en Remove [spm] track paramter in URL
// @description  移除链接中的spm跟踪参数
// @author       shc0743
// @match        http*://*/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        none
// @license      GPL-3.0
// @supportURL   https://github.com/shc0743/MyUtility/issues/new
// @run-at       document-start
// ==/UserScript==

/*
Description:
说明:
 
    This user script removes the spm paramter in <a href> elements.
    此脚本移除 <a href> 元素中的spm参数。
    
    If it doesn't work, try refreshing it a few times or wait a while.
    若无法生效,请尝试刷新几次或等一会。
 
    Examples:
    示例:
    
    https://www.bilibili.com/video/av170001?spm_id_from=114514
    -> https://www.bilibili.com/video/av170001
 
    https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514&query2=data3
    -> https://www.bilibili.com/video/av170001?query1=arg2&query2=data3
 
    https://www.bilibili.com/video/av170001?spm=114514.1919810#hash
    -> https://www.bilibili.com/video/av170001#hash
 
    https://www.bilibili.com/video/av170001?spm=114514.1919810&query2=data3#hash1
    -> https://www.bilibili.com/video/av170001?query2=data3#hash1
*/

(function () {
    'use strict';

    // Your code here...

    var track_args_list = [
        { 'domain': '*', 'keyword': 'spm' },
        { 'domain': '*', 'keyword': 'spm_id_from' },
        { 'domain': '*', 'keyword': 'from_source' },
    ];

return (function (global) {

    //var expr = /\?[\s\S]*spm/i;

    /**
     * 去除字符串中的spm参数
     * @param {String} str URL to remove spm
     * @returns 去除spm后的结果
     */
    var remove_spm = function (str) {
        if (typeof (str) != 'string') return str;
        var newstr = '';
        var len = str.length;
        // 只去除查询参数部分,避免正常url被替换而导致404
        var hash_part_begin = str.indexOf('#');
        var query_part_begin = str.indexOf('?');
        if (query_part_begin == -1 ||
            (hash_part_begin != -1 && query_part_begin > hash_part_begin))
            { return str; } // 没有查询参数或?在#后面,直接返回
        newstr = str.substring(0, query_part_begin);
        var domain = '';
        {
            let index = str.indexOf('://');
            if (index + 1) {
                index = str.indexOf('/', index + 3);
                if (index + 1) {
                    domain = str.substring(0, index);
                }
            }
        }

        for (let i = query_part_begin, need_break; i < len; ++i) {
            for (let j = 0; j < track_args_list.length; ++j) {
                if (!(track_args_list[j].domain == '*' ||
                    domain.indexOf(track_args_list[j].domain) != -1)) {
                    need_break = false;
                    break;
                }
                need_break = true;
                if (track_args_list[j].keyword == str.substring(i,
                    i + track_args_list[j].keyword.length - 0)) {
                    // 检测到
                    while ((++i) < len) {
                        if (str[i] == '&') { // 不能单独保留一个 & 号
                            i++;
                            break; // 去掉
                        }
                        if (str[i] == '#') break; // 保留hash部分
                    }
                    if (i == len) break; // 越界,直接break,以免url出现undefined
                }
                need_break = false;
            }
            if (need_break) break;
            newstr += str[i];
        }

        var _lastchar;
        for (let i = 0; i < newstr.length; ++i) {
            _lastchar = newstr[newstr.length - 1];
            if (_lastchar == '?' || _lastchar == '&') { // 如果移除后只剩下 ? 或 &
                newstr = newstr.substring(0, newstr.length - 1); // 去掉
            } else break;
        }
        // Bug-Fix:
        // https://example.com/example?q1=arg&spm=123#hash1
        // -> https://example.com/example?q1=arg&#hash1
        //     Invalid URL syntax at            ^^
        newstr = newstr.replace(/\&\#/igm, '#');
        newstr = newstr.replace(/\?\#/igm, '#');
        return newstr;
    }
    var test_spm = function (str) {
        for (let tracker of track_args_list)
            if (new RegExp(tracker, 'i').test(str))
                return true;
        return false;
    };
    var _realwindowopen = window.open;
    var _realhistorypushState = window.history.pushState;
    var _realhistoryreplaceState = window.history.replaceState;

    var _link_click = function (event) {
        if (!(/http/i.test(this.href))) return;
        event.preventDefault();
        // 防止被再次加入spm
        this.href = remove_spm(this.href);
        _realwindowopen(this.href, this.target || '_self');
        return false;
    };
    var _link_mouseover = function () {
        if (test_spm(this.href))
            this.href = remove_spm(this.href);
    };
    var linkclickhandlerinit = function () {
        var el = document.querySelectorAll('a[href]');
        for (let i = el.length - 1; i >= 0; --i) {
            if (test_spm(el[i].href)) {
                // 链接已经被加入spm , 需要移除
                el[i].href = remove_spm(el[i].href);
            }
            el[i].removeEventListener('click', _link_click);
            el[i].addEventListener('click', _link_click, true);
            el[i].removeEventListener('mouseover', _link_mouseover);
            el[i].addEventListener('mouseover', _link_mouseover, false);
        }
    };
    window.addEventListener('load', function (event) {
        window.setInterval(linkclickhandlerinit, 5000);
        window.setTimeout(linkclickhandlerinit, 1000);
        window.setTimeout(linkclickhandlerinit, 500);
        window.setTimeout(linkclickhandlerinit, 1);
        try {
            var wopen = function (url, target, features) {
                return _realwindowopen.call(window,
                    remove_spm(url),
                    target,
                    features);
            };
            var hp = function (data, title, url) {
                return _realhistorypushState.call(
                    window.history, data, title,
                    remove_spm(url));
            };
            var hr = function (data, title, url) {
                return _realhistoryreplaceState.call(
                    window.history, data, title,
                    remove_spm(url));
            };
            wopen.toString =
            hp.toString =
            hr.toString =
            function () {
                return `function () {\n    [native code]\n}`
            };
            Object.defineProperty(window, 'open', {
                value: wopen,
                writable: false,
                enumerable: true,
                configurable: true
            }); // 重定义window.open 以阻止弹出窗口中的spm
            Object.defineProperty(window.history, 'pushState', {
                value: hp,
                writable: false,
                enumerable: true,
                configurable: true
            }); // 重定义history.pushState
            Object.defineProperty(window.history, 'replaceState', {
                value: hr,
                writable: false,
                enumerable: true,
                configurable: true
            }); // 重定义history.replaceState
        }
        catch (error) {
            console.warn("This browser doesn't support redefining" +
                " window.open , so [SpmBlockTool] cannot remove" +
                " spm in popup window.\nError:", error);
        }
    });

    // 移除当前页面的spm
    // 当然,实际上spm已经在userscript加载前被发送到服务器,
    // 所以该功能仅美化url.
    // 如果要禁用该功能,删除下面一行开头的斜杠。
    //if(0)
    // Remove spm from current page
    // Of course, in fact, SPM has been sent to the server 
    // before userscript is loaded, so this function only beautifies the URL.
    // If you want to disable this feature, remove the slash
    // at the beginning of the following line:
    //if(0)
    if (test_spm(location.href)) {
        _realhistoryreplaceState.call(window.history,
            {}, document.title,
            remove_spm(location.href));
    }

    /*
    var test_urls = [
        'https://www.bilibili.com/video/BV18X4y1N7Yh',
        'https://www.bilibili.com/video/BV18X4y1N7Yh?spm_id_from=114514',
        'https://www.bilibili.com/video/BV18X4y1N7Yh?spm=114514.1919810',
        'https://www.bilibili.com/video/BV18X4y1N7Yh?spm_id_from=114514.123',

        'https://www.bilibili.com/video/av170001',
        'https://www.bilibili.com/video/av170001?spm_id_from=114514',
        'https://www.bilibili.com/video/av170001?spm=114514.1919810',
        'https://www.bilibili.com/video/av170001?spm_id_from=114514.123',

        'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514',
        'https://www.bilibili.com/video/av170001?query1=arg2&spm=114514.1919810',
        'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514.123',
        'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514',
        'https://www.bilibili.com/video/av170001?query1=arg2&spm=114514.1919810',
        'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514.123',

        'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514&query2=data3',
        'https://www.bilibili.com/video/av170001?query1=arg2&spm=114514.1919810&query2=data3',

        'https://www.bilibili.com/video/av170001?spm_id_from=114514#hash',
        'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514#hash1',
        'https://www.bilibili.com/video/av170001?query1=arg2&spm=114514.1919810#hash1',

        'https://www.bilibili.com/video/av170001?spm_id_from=114514&query2=data3#hash1',
        'https://www.bilibili.com/video/av170001?spm=114514.1919810&query2=data3#hash1',
    ];
    for(let i=0;i<test_urls.length;++i){
        let el=document.createElement('a');
        el.href=test_urls[i];
        el.innerHTML=i+1 + '';
        document.documentElement.appendChild(el);
    }
    for(let i=0;i<test_urls.length;++i){
        let el=document.createElement('a');
        el.href=test_urls[i];
        el.innerHTML=i+1 + ' blank';
        el.target='_blank';
        document.documentElement.appendChild(el);
    }
    */

})(window);

})();

QingJ © 2025

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