如何通过用户脚本拦截YouTube的特定GET请求?
拦截YouTube搜索建议请求的问题
我想拦截YouTube点击搜索栏时发起的特定GET请求:https://suggestqueries-clients6.youtube.com/complete/search?...,不需要这些搜索建议。试过清除Cookie、在网站设置里关闭该功能都没用,于是尝试用Tampermonkey写用户脚本,但以下三个方案都失败了:
方案一:监听beforesendheaders事件
// ==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); } }); })();
问题:请求仍会发起,console.log()也未执行。原因是beforesendheaders不是标准DOM事件,Tampermonkey也未内置该事件监听逻辑,所以此方法完全无效。
方案二:重写fetch方法
(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); } }; })();
问题:无效。原因是YouTube可能使用了封装后的fetch方法,且脚本注入时机太晚,页面代码已经引用了原始fetch,导致重写无法覆盖。
方案三:重写XMLHttpRequest的send方法
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._url并非XMLHttpRequest实例的默认属性,没有保存请求URL的逻辑,无法判断目标请求地址。
可行的解决方案
要成功拦截该请求,需同时覆盖fetch和XMLHttpRequest的关键方法,且确保脚本在页面代码加载前注入:
// ==UserScript== // @name YouTube Search Suggestion Blocker // @namespace http://tampermonkey.net/ // @version 0.1 // @description Block YouTube search suggestion requests // @author You // @match https://www.youtube.com/* // @run-at document-start // 关键:在页面脚本加载前执行 // @grant none // ==/UserScript== (function() { 'use strict'; const BLOCK_URL = "https://suggestqueries-clients6.youtube.com/complete/search"; // 拦截fetch请求 const originalFetch = window.fetch; window.fetch = function(input, init) { let url = typeof input === 'string' ? input : input.url; if (url.startsWith(BLOCK_URL)) { console.log('Blocked fetch request:', url); // 返回模拟的空搜索建议响应,避免页面报错 return Promise.resolve({ ok: true, json: () => Promise.resolve([]), text: () => Promise.resolve('[]') }); } return originalFetch.apply(this, arguments); }; // 拦截XMLHttpRequest请求 const originalXhrOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { this._targetUrl = url; // 保存请求URL到实例属性 originalXhrOpen.apply(this, arguments); }; const originalXhrSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function() { if (this._targetUrl?.startsWith(BLOCK_URL)) { console.log('Blocked XHR request:', this._targetUrl); // 模拟请求完成事件,避免页面等待超时 this.onload?.call(this, { target: { responseText: '[]', status: 200 } }); return; } originalXhrSend.apply(this, arguments); }; })();
关键说明
@run-at document-start:确保脚本在页面所有代码加载前执行,保证重写的方法能覆盖页面的请求调用。- 同时拦截
fetch和XMLHttpRequest:YouTube可能用其中一种或两种方式发起搜索建议请求。 - 返回模拟响应:直接返回空的搜索建议数组,避免页面因请求失败出现错误或异常行为。
内容的提问来源于stack exchange,提问作者derpascal
相关产品推荐
相关产品推荐

