Получение контроля над каждым изменением атрибута src в DOM

Я пишу код Javascript, который должен отслеживать новые элементы сценария и блокировать несколько известных источников.

Чтобы поймать их, я пытался использовать MutationObserver и __ defineSetter __ , оба могут отслеживать изменение 'src', но только после того, как HTTP-запрос уже отправлен, поэтому даже если я изменю src , он на самом деле не блокируется.

window.HTMLScriptElement.prototype.__defineSetter__('src', function (d) 
    {
        console.log("HTMLScriptElement: ",d);
        if (d.indexOf('localhost') != -1) {
            //BLOCK SCRIPT
        }
    });

    new MutationObserver(function (a) {
        a.forEach((e) => {
            e.addedNodes.forEach((z) => 
            {
                if (z.nodeName.toLowerCase() == "script" && z.src.indexOf('localhost') != -1) 
                {
                    //BLOCK SCRIPT
                }
            })
        })
    }).observe(window.document, {
        attributes: true,
        childList:true,
        subtree:true
    });

person Liron Avital    schedule 02.09.2020    source источник
comment
Одного MutationObserver достаточно, но вам нужно 1) удалить элемент, а не просто изменить его src, затем создать новый элемент, если хотите, и 2) также проверить вложенные узлы, потому что addNodes не сглаживается, поэтому какой-то сайт может добавить элемент контейнера со скриптами внутри.   -  person wOxxOm    schedule 02.09.2020


Ответы (1)


Вы можете использовать сервис-воркеры для перехвата сетевых запросов. Что-то вроде этого должно помочь:

self.addEventListener('fetch', function (event) {
    const blockedUrls = [
        //...
    ];
    if (blockedUrls.some(x => event.request.url.startsWith(x))) {
        event.respondWith(new Response('blocked', { status: 401, statusText: 'Unauthorized' }));
    }
});
person Guerric P    schedule 02.09.2020
comment
Вы должны записать это в отдельный файл (предназначенный сервис-воркеру) и зарегистрировать его с помощью navigator.serviceWorker.register('./sw-test/sw.js'). Для получения дополнительной информации: developer.mozilla.org/en- США/документы/Интернет/API/Service_Worker_API/ - person Guerric P; 02.09.2020
comment
Я не могу использовать сервис-воркеров, так как мой код работает на некоторых сайтах, отличных от моего. Если я правильно понимаю, мне нужно его установить - поэтому я не могу его использовать - person Liron Avital; 02.09.2020
comment
Тогда действительно это не сработает, поскольку источник сценария сервисного работника должен совпадать с текущим источником. - person Guerric P; 02.09.2020
comment
В любом случае спасибо, есть еще идеи? - person Liron Avital; 02.09.2020
comment
К сожалению, у меня нет других идей, я действительно сомневаюсь, что это возможно. - person Guerric P; 02.09.2020
comment
Я не знаю, нашли ли вы уже решение, но вы должны попробовать аналогичный подход к HTMLScriptElement.prototype.__defineSetter__('src', function (d), но с Прокси. Замените родной HTMLScriptElement на свой Proxy (построенный из родного HTMLScriptElement). Я ответил на вопрос с аналогичным решением здесь: «перехватывать веб-уведомления html5 в среде браузера»> stackoverflow.com/questions/57523910/ - person Guerric P; 08.09.2020