Сделать возможность подмены запроса на свою функцию

Запросы функционала
  • Недавно в модуль "Сеть" добавили экшены для замены запросов. Но бывают ситуации, когда тело запроса недостаточно менять просто по фильтрам. Например, содержимое закодировано в base64, в котором лежит json, часть значений которого генерируется сайтом (идентификаторы, таймстампы). Поэтому нужна возможность добавить функцию, типа: function(request){}, где request - объект запроса.

    Я сейчас пытаюсь подменять через экшен "Выполнять при каждой загрузке страницы в браузере", типа такого:

    (function() {
        const TARGET_PATTERN = 'myurl';
    
        const originalFetch = window.fetch;
        window.fetch = function(input, init) {
            const url = new URL(
                typeof input === 'string' ? input : input.url,
                location.href
            );
            
            if (url.pathname.endsWith(TARGET_PATTERN)) {
                setFptImageParams(url.searchParams);
                input = url.toString();
            }
            
            return originalFetch(input, init);
        };
    
        const originalOpen = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function(method, url) {
            const parsedUrl = new URL(url, location.href);
            if (parsedUrl.pathname.endsWith(TARGET_PATTERN)) {
                makeReplace(parsedUrl.searchParams);
                url = parsedUrl.toString();
            }
            originalOpen.call(this, method, url);
        };
    
        function makeReplace(params) {
            // Моя бизнес логика
        }
    })();
    

    Но после применения этого кода бас перестает видеть элементы на странице при поиске по селекторам.

  • @thepappo

    Я делал множество раз подобное и у меня работало.

    Может использовать немного другой подход(код не тестировал никак совсем):

    (function() {
        const TARGET_PATTERN = 'myurl';
    
        // Store original fetch in window object with a unique key
        if (!window.__originalFetch) {
            window.__originalFetch = window.fetch;
        }
    
        // Overwrite fetch
        Object.defineProperty(window, 'fetch', {
            value: function(input, init) {
                const url = new URL(
                    typeof input === 'string' ? input : input.url,
                    location.href
                );
                
                if (url.pathname.endsWith(TARGET_PATTERN)) {
                    setFptImageParams(url.searchParams);
                    input = url.toString();
                }
                
                return window.__originalFetch(input, init);
            },
            configurable: true  // Allows redefining the property later if needed
        });
    
        // Store original XMLHttpRequest.open
        if (!window.__originalXHROpen) {
            window.__originalXHROpen = XMLHttpRequest.prototype.open;
        }
    
        // Overwrite XMLHttpRequest.open
        Object.defineProperty(XMLHttpRequest.prototype, 'open', {
            value: function(method, url) {
                const parsedUrl = new URL(url, location.href);
                if (parsedUrl.pathname.endsWith(TARGET_PATTERN)) {
                    makeReplace(parsedUrl.searchParams);
                    url = parsedUrl.toString();
                }
                window.__originalXHROpen.call(this, method, url);
            },
            configurable: true
        });
    
        function makeReplace(params) {
            // Моя бизнес логика
        }
    })();
    
  • @sergerdn через Object.defineProperty тоже пробовал, не искались элементы. Но попробую твой вариант.

    Ну а смысл топика изначально в том, чтобы дать возможность через кубик подмены передавать свою функцию, раз такой функционал есть все равно.