您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Blocks ServiceWorker on all websites. Advanced whitelist management with manual domain removal. Prevents PWA installations and background sync.
// ==UserScript== // @name Reject ServiceWorker Auto (Simple) // @namespace rejectserviceWorkerAuto // @version 1.7.5 // @description Blocks ServiceWorker on all websites. Advanced whitelist management with manual domain removal. Prevents PWA installations and background sync. // @author hongmd // @license MIT // @homepageURL https://github.com/hongmd/userscript-improved // @supportURL https://github.com/hongmd/userscript-improved/issues // @match *://*/* // @run-at document-start // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @compatible ScriptCat // @compatible Tampermonkey // @compatible Greasemonkey // @noframes // ==/UserScript== 'use strict'; // Constants for consistent messaging and configuration const MESSAGES = { // Status messages BLOCKED: "ServiceWorker registration blocked", WHITELISTED: "Domain whitelisted - ServiceWorker allowed", ALREADY_EXISTS: "Domain already in whitelist", NOT_IN_WHITELIST: "Domain is not in whitelist", // Alert messages ADDED_TO_WHITELIST: (hostname) => `✅ Added "${hostname}" to whitelist!\n\nServiceWorker will NOT be blocked here.\nReload page to take effect.`, REMOVED_FROM_WHITELIST: (hostname) => `❌ Removed "${hostname}" from whitelist!\n\nServiceWorker will be blocked here.\nReload page to take effect.`, ALREADY_WHITELISTED: (hostname) => `Info: "${hostname}" is already in whitelist.`, NOT_WHITELISTED: (hostname) => `"${hostname}" is not in whitelist.`, WHITELIST_EMPTY: "📋 Whitelist is empty!\n\nNo domains to remove.", DOMAIN_NOT_FOUND: (domain, currentList) => `❌ Domain "${domain}" not found in whitelist.\n\nCurrent whitelist: ${currentList}`, MANUAL_REMOVAL_SUCCESS: (domain) => `✅ Removed "${domain}" from whitelist!\n\nServiceWorker will be blocked on this domain.\nReload the page if you're currently on it.`, // Error messages INIT_ERROR: "Failed to initialize menu items - falling back to blocking mode", STORAGE_ERROR: "Invalid stored data, resetting to empty array", INJECTION_ERROR: "Failed to block ServiceWorker - using fallback method", // Menu commands SHOW_WHITELIST: "📋 Show Whitelist Info", BLOCK_HERE: "🚫 Block ServiceWorker Here", ALLOW_HERE: "✅ Allow ServiceWorker Here", MANUAL_BLOCK: "🔧 Manual Block Now", REMOVE_FROM_WHITELIST: "🗑️ Remove from Whitelist" }; const SCRIPT_NAME = 'rejectserviceWorkerAuto'; const STORAGE_PREFIX = `autoinject${SCRIPT_NAME}`; const LOG_PREFIX = 'RSA:'; console.log(`${LOG_PREFIX} Script loaded for:`, document.domain); let injectedStatus = false; let hostArray = []; /** * Injects ServiceWorker blocking logic using primary and fallback methods * Primary method: Overrides navigator.serviceWorker with a blocking proxy object * Fallback method: Overrides the register method directly for older browsers * Prevents PWA installations and background sync functionality */ function inject() { // Skip if running in frames or already injected if (window.self !== window.top) return; if (injectedStatus) return; // Block ServiceWorker registration if (typeof navigator !== 'undefined' && navigator.serviceWorker) { try { Object.defineProperty(navigator, 'serviceWorker', { value: { register: () => Promise.reject(new Error("ServiceWorker registration blocked by RSA script")), getRegistration: () => Promise.resolve(undefined), getRegistrations: () => Promise.resolve([]), ready: Promise.reject(new Error("ServiceWorker blocked")) }, writable: false, configurable: false }); console.log(`${LOG_PREFIX} ${MESSAGES.BLOCKED} on`, document.domain); } catch (e) { // Fallback method for older browsers navigator.serviceWorker.register = () => Promise.reject(new Error("ServiceWorker registration blocked")); console.warn(`${LOG_PREFIX} ${MESSAGES.INJECTION_ERROR} on`, document.domain); } } injectedStatus = true; } /** * Adds the current domain to the whitelist, allowing ServiceWorker registration * Updates persistent storage and provides user feedback * Requires page reload to take effect */ function addHost() { const hostname = location.hostname; if (!hostArray.includes(hostname)) { hostArray.push(hostname); GM_setValue(STORAGE_PREFIX, JSON.stringify(hostArray)); console.log(`${LOG_PREFIX} Added`, hostname, 'to whitelist'); alert(MESSAGES.ADDED_TO_WHITELIST(hostname)); } else { alert(MESSAGES.ALREADY_WHITELISTED(hostname)); } } /** * Displays comprehensive whitelist information including current domain status * Shows total count and lists all whitelisted domains * Provides clear visual indicators for whitelist status */ function showWhitelistInfo() { const hostname = location.hostname; const isWhitelisted = hostArray.includes(hostname); const currentStatus = isWhitelisted ? "WHITELISTED" : "BLOCKED"; const statusIcon = isWhitelisted ? "✅" : "🚫"; const totalSites = hostArray.length; let message = `${statusIcon} Current domain: ${hostname}\n`; message += `Status: ${currentStatus}\n\n`; message += `📋 Total whitelisted sites: ${totalSites}\n`; if (totalSites > 0) { message += "🔸 " + hostArray.join("\n🔸 "); } alert(message); } /** * Removes the current domain from the whitelist, enabling ServiceWorker blocking * Updates persistent storage and provides user feedback * Requires page reload to take effect */ function removeHost() { const hostname = location.hostname; const index = hostArray.indexOf(hostname); if (index > -1) { hostArray.splice(index, 1); GM_setValue(STORAGE_PREFIX, JSON.stringify(hostArray)); console.log(`${LOG_PREFIX} Removed`, hostname, 'from whitelist'); alert(MESSAGES.REMOVED_FROM_WHITELIST(hostname)); } else { alert(MESSAGES.NOT_WHITELISTED(hostname)); } } /** * Allows user to remove any domain from the whitelist by entering it manually * Provides a text input dialog for domain removal * Useful for managing whitelist without visiting each domain */ function removeFromWhitelist() { if (hostArray.length === 0) { alert(MESSAGES.WHITELIST_EMPTY); return; } const currentList = hostArray.join(", "); const domainToRemove = prompt( `🗑️ Remove domain from whitelist:\n\nCurrent whitelist: ${currentList}\n\nEnter domain to remove (without https://):`, "" ); if (!domainToRemove?.trim()) return; const cleanDomain = domainToRemove.trim().toLowerCase(); const index = hostArray.findIndex(host => host.toLowerCase() === cleanDomain); if (index > -1) { const removedDomain = hostArray.splice(index, 1)[0]; GM_setValue(STORAGE_PREFIX, JSON.stringify(hostArray)); console.log(`${LOG_PREFIX} Manually removed`, removedDomain, 'from whitelist'); alert(MESSAGES.MANUAL_REMOVAL_SUCCESS(removedDomain)); } else { alert(MESSAGES.DOMAIN_NOT_FOUND(cleanDomain, currentList)); } } /** * Initializes the script by loading stored whitelist data and setting up menu commands * Handles data validation, error recovery, and dynamic menu configuration * Automatically injects blocking logic for non-whitelisted domains */ function initializeScript() { try { // Safe JSON parsing with validation const storedData = GM_getValue(STORAGE_PREFIX, "[]"); if (typeof storedData === 'string' && storedData.trim()) { hostArray = JSON.parse(storedData); // Validate that result is an array if (!Array.isArray(hostArray)) { console.warn(`${LOG_PREFIX} ${MESSAGES.STORAGE_ERROR}`); hostArray = []; } } else { hostArray = []; } const hostname = location.hostname; const isWhitelisted = hostArray.includes(hostname); // Always show status info GM_registerMenuCommand(MESSAGES.SHOW_WHITELIST, showWhitelistInfo); GM_registerMenuCommand(MESSAGES.REMOVE_FROM_WHITELIST, removeFromWhitelist); if (isWhitelisted) { // Current domain is whitelisted GM_registerMenuCommand(MESSAGES.BLOCK_HERE, removeHost); GM_registerMenuCommand(MESSAGES.MANUAL_BLOCK, inject); console.log(`${LOG_PREFIX}`, hostname, MESSAGES.WHITELISTED); } else { // Current domain is not whitelisted (blocked by default) inject(); GM_registerMenuCommand(MESSAGES.ALLOW_HERE, addHost); console.log(`${LOG_PREFIX} Auto-blocked ServiceWorker for`, hostname); } } catch (err) { console.error(`${LOG_PREFIX} ${MESSAGES.INIT_ERROR}`); console.error(err); // Fallback: always inject if there's an error inject(); } } // Start the script initializeScript();