Search code examples
javascripttampermonkeyuserscripts

How can I block specific requests in a website with a userscript?


I am trying to prevent block a specific GET request made by YouTube. When the searchbar is clicked, a GET request to https://suggestqueries-clients6.youtube.com/complete/search?... is performed, which fetches search-suggestions. I don't want these search suggestions.

I tried clearing cookies, and turning it off in the settings but to no avail. So then I tried it with Tampermonkey.

Here is what I tried:

// ==UserScript==
// @name         YouTube URL Blocker
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Block GET requests to specific URLs on YouTube.
// @author       me
// @match        https://www.youtube.com/*
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict';

    var blockedURL = "https://suggestqueries-clients6.youtube.com/complete/search";

    document.addEventListener("beforesendheaders", function(e) {
        var requestDetails = e.detail;
        if (requestDetails.method === "GET" && requestDetails.url.startsWith(blockedURL)) {
            e.preventDefault();
            console.log("GET request to blocked URL blocked:", requestDetails.url);
        }
    });

})();

This unfortunately did not work. The request was still appearing and the console.log() also did not execute.

I then tried:

(function() {
'use strict';

    var blockedURL = "https://suggestqueries-clients6.youtube.com";
    
    window.originalFetch = window.fetch;
    
    window.fetch = function(url, options) {
        if (url.startsWith(blockedURL)) {
            console.log("Fetch request to blocked URL:", url);
            return;
        } else {
            return window.originalFetch(url, options);
        }
    };

})();

Sadly, this had the same results and did not work either.

My last attempt was:

var blockedURL = "https://suggestqueries-clients6.youtube.com";

XMLHttpRequest.prototype.realSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
    if (this._url && this._url.startsWith(blockedURL)) {
        console.log("XMLHttpRequest blocked:", this._url);
        return;
    }
    this.realSend.apply(this, arguments);
};

This also did not work.


Solution

  • Use GM_webRequest:

    // ==UserScript==
    // @name         YouTube URL Blocker
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  Block GET requests to specific URLs on YouTube.
    // @author       me
    // @match        https://www.youtube.com/*
    // @grant        GM_webRequest
    // ==/UserScript==
    
    (function() {
        'use strict';
    
        const blockedSelector = 'https://suggestqueries-clients6.youtube.com/complete/search*';
    
        GM_webRequest([
            { selector: blockedSelector, action: 'cancel' },
        ], (info, message, details) => {
           console.log('GET request to blocked URL blocked:', info, message, details);
        });
    )();
    

    or @webRequest:

    // ==UserScript==
    // @name         YouTube URL Blocker
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  Block GET requests to specific URLs on YouTube.
    // @author       me
    // @match        https://www.youtube.com/*
    // @webRequest   {"selector":"https://suggestqueries-clients6.youtube.com/complete/search*","action":"cancel"}
    // ==/UserScript==
    
    // rest of code
    

    In this case, GM_webRequest and @webRequest have almost identical behaviour — only difference is that with @webRequest, the blocking rule is applied as soon as possible (i.e. before the userscript is loaded).