Block All Client-Side Redirects

Prevents most client-side navigations (links, forms, JS redirects, meta refresh) in Safari/iOS or any browser with a userscript manager.

Versión del día 15/8/2025. Echa un vistazo a la versión más reciente.

// ==UserScript==
// @name         Block All Client-Side Redirects
// @namespace    https://github.com/osuobiem
// @version      1.0
// @description  Prevents most client-side navigations (links, forms, JS redirects, meta refresh) in Safari/iOS or any browser with a userscript manager.
// @author       Gabriel Osuobiem
// @match        *://*/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    function notify(msg) {
        console.log('[NoRedirect]', msg);
        alert('Blocked navigation:\n' + msg);
    }

    function blockMetaRefresh() {
        document.querySelectorAll('meta[http-equiv="refresh"]').forEach(m => m.remove());
    }

    // Block clicks on links
    document.addEventListener('click', e => {
        const a = e.target.closest && e.target.closest('a[href]');
        if (!a) return;
        e.preventDefault();
        notify(a.href);
    }, true);

    // Block form submissions
    document.addEventListener('submit', e => {
        e.preventDefault();
        notify(e.target && e.target.action || location.href);
    }, true);

    // Stop meta refresh tags
    new MutationObserver(blockMetaRefresh).observe(document.documentElement, { childList: true, subtree: true });

    // Initial meta cleanup
    blockMetaRefresh();

    // Override location methods
    try {
        const L = location;
        L.assign = new Proxy(L.assign, { apply(_t, _th, args) { notify(args && args[0]); } });
        L.replace = new Proxy(L.replace, { apply(_t, _th, args) { notify(args && args[0]); } });
        L.reload = new Proxy(L.reload, { apply() { notify('(reload)'); } });
    } catch (_) { }

    // Override window.open
    try {
        window.open = new Proxy(window.open, { apply(_t, _th, args) { notify(args && args[0]); return null; } });
    } catch (_) { }

    // Override History API
    try {
        history.pushState = new Proxy(history.pushState, { apply() { notify('(pushState)'); } });
        history.replaceState = new Proxy(history.replaceState, { apply() { notify('(replaceState)'); } });
    } catch (_) { }

    // Add CSP to block some navigations
    try {
        const meta = document.createElement('meta');
        meta.httpEquiv = 'Content-Security-Policy';
        meta.content = "navigate-to 'none'; form-action 'none'";
        document.head && document.head.appendChild(meta);
    } catch (_) { }

    console.log('[NoRedirect] Redirect blocking active.');
})();
长期地址
遇到问题?请前往 GitHub 提 Issues。