Open AdamWr opened 3 months ago
Related to https://github.com/AdguardTeam/AdguardFilters/issues/175034 and https://github.com/AdguardTeam/AdguardFilters/issues/174876
These websites use onreadystatechange to check if 4 events were fired and #%#//scriptlet('prevent-xhr', 'pagead2.googlesyndication.com') doesn't work because currently only 2 events are invoked.
onreadystatechange
events
#%#//scriptlet('prevent-xhr', 'pagead2.googlesyndication.com')
Steps to reproduce:
example.org#%#//scriptlet('prevent-xhr', 'pagead2.googlesyndication.com')
https://example.org/
In browser console run:
(() => { const checkDection = (detected) => { if (detected) { alert('AdBlocker detected'); return; } const allEventsPassed = xhrEvents.every((state) => state); if (!allEventsPassed) { alert('AdBlocker detected'); return; } // No AdBlocker detected, do something console.log('No AdBlocker detected'); }; const url = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'; const xhrEvents = [false, false, false, false]; const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { xhrEvents[xhr.readyState - 1] = true; if (xhr.readyState === 4) { checkDection(); } }; try { xhr.open("GET", url, true); xhr.send(); } catch (ex) { checkDection(true); } })();
Probably changing this part: https://github.com/AdguardTeam/Scriptlets/blob/804c53527008e62ffcd296e3f36543c472b96fe5/src/scriptlets/prevent-xhr.js#L184-L223
to something like:
should fixes it.
Related to https://github.com/AdguardTeam/AdguardFilters/issues/175034 and https://github.com/AdguardTeam/AdguardFilters/issues/174876
These websites use
onreadystatechange
to check if 4events
were fired and#%#//scriptlet('prevent-xhr', 'pagead2.googlesyndication.com')
doesn't work because currently only 2events
are invoked.Steps to reproduce:
https://example.org/
In browser console run:
Probably changing this part: https://github.com/AdguardTeam/Scriptlets/blob/804c53527008e62ffcd296e3f36543c472b96fe5/src/scriptlets/prevent-xhr.js#L184-L223
to something like:
Code:
```js forgedRequest.addEventListener('readystatechange', () => { Object.defineProperty(thisArg, 'readyState', { value: forgedRequest.readyState, writable: true }); // it seems that - thisArg.readyState = forgedRequest.readyState - doesn't work, but maybe I didn't check it correctly const stateEvent = new Event("readystatechange"); switch (forgedRequest.readyState) { case 1: thisArg.dispatchEvent(stateEvent); const loadStartEvent = new Event("loadstart"); thisArg.dispatchEvent(loadStartEvent); break; case 2: thisArg.dispatchEvent(stateEvent); const progressEvent = new Event("progress"); thisArg.dispatchEvent(progressEvent); break; case 3: thisArg.dispatchEvent(stateEvent); const loadEvent = new Event("load"); thisArg.dispatchEvent(loadEvent); break; case 4: const { readyState, responseURL, responseXML, statusText } = forgedRequest; // Mock response object Object.defineProperties(thisArg, { // original values readyState: { value: readyState, writable: false }, statusText: { value: statusText, writable: false }, // If the request is blocked, responseURL is an empty string responseURL: { value: responseURL || thisArg.xhrData.url, writable: false }, responseXML: { value: responseXML, writable: false }, // modified values status: { value: 200, writable: false }, response: { value: modifiedResponse, writable: false }, responseText: { value: modifiedResponseText, writable: false } }); // Mock events setTimeout(() => { thisArg.dispatchEvent(stateEvent); const loadEndEvent = new Event('loadend'); thisArg.dispatchEvent(loadEndEvent); }, 1); } hit(source); }); ```should fixes it.