Я пытаюсь написать веб-расширение, которое останавливает запросы из списка URL-адресов, предоставленного локально, получает ответ URL-адреса, анализирует его определенным образом и на основе результатов анализа блокирует или не блокирует запрос. Это вообще возможно? Браузер не имеет значения. Если можно, не могли бы вы привести несколько примеров?
Я пытался сделать это с расширениями Chrome, но похоже, что это невозможно. Я слышал, что это возможно в мозилле, хотя
Я думаю, что это возможно только с использованием старого API webRequestBlocking, который Chrome удаляет как часть Manifest v3 . К счастью, Firefox планирует и дальше поддерживать блокировку веб-запросов даже при переходе на манифест v3 (подробнее здесь).
Что касается реализации, я настоятельно рекомендую обратиться к документации MDN для webRequest, в частности к их разделу об изменении ответов и их документации по методу filterResponseData.
Mozilla также предоставила отличный пример проекта, который демонстрирует, как добиться чего-то очень близкого к тому, что, как мне кажется, вы хотите сделать.
Ниже я немного изменил их код background.js
, чтобы он был немного ближе к тому, что вы хотите сделать:
function listener(details) {
if (mySpecialUrls.indexOf(details.url) === -1) {
// Ignore this url, it's not on our list.
return {};
}
let filter = browser.webRequest.filterResponseData(details.requestId);
let decoder = new TextDecoder("utf-8");
let encoder = new TextEncoder();
filter.ondata = event => {
let str = decoder.decode(event.data, {stream: true});
// Just change any instance of Example in the HTTP response
// to WebExtension Example.
str = str.replace(/Example/g, 'WebExtension Example');
filter.write(encoder.encode(str));
filter.disconnect();
}
// This is a BlockingResponse object, you can set parameters here to e.g. cancel the request if you want to.
// See: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/BlockingResponse#type
return {};
}
browser.webRequest.onBeforeRequest.addListener(
listener,
// 'main_frame' means this will only affect requests for the main frame of the browser (e.g. the HTML for a page rather than the images, CSS, etc. that are loaded afterwards). You might want to look into whether you want to expand this.
{urls: ["*://*/*"], types: ["main_frame"]},
["blocking"]
);
Исправление: Приведенный выше пример работает правильно только в том случае, если данные ответа помещаются в один блок. Если он больше (и вы все еще хотите проверить все данные ответа), вам нужно будет поместить все данные в буфер, а затем работать с ним после того, как все данные будут получены. См. документ здесь для получения дополнительной информации: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/StreamFilter/ondata#webextension_examples (раздел кода под названием " В этом примере все буферы объединены в один буфер, я думаю, это будет представлять для вас наибольший интерес).
С точки зрения использования этого API для блокировки ответов, данные возвращаются с этого URL только в том случае, если вы вызываете filter.write()
, поэтому, если вам не нравится ответ, вы можете просто не вызывать его (просто вызовите filter.close()
), и будет возвращен пустой ответ. . Вы также можете вернуть только часть полного тела ответа, указав только те биты, которые вы хотите вернуть.
Спасибо! Отличный и развернутый ответ! Буду разбираться во всем подробнее! Точнее, я пытаюсь создать блокировщик рекламы, который блокирует только ту рекламу, которую считает вредоносной, на основе структуры URL-адреса и ответа, который дает URL-адрес. У меня есть список из 57000+ URL-адресов из списка фильтров блокировщика рекламы, и я создал достаточно, чтобы заблокировать все эти URL-адреса, но мне нужно их проанализировать. Может быть, вы можете добавить больше информации на основе предоставленных мной фактов?
@MartynasJurkėnas извините за медленный ответ! Я добавил дополнительную информацию, которая, надеюсь, поможет :)
Пожалуйста, используйте chrome.declarativeNetRequest.