0

I have this userscript for duolingo.com that used to intercept and log every network request url, but no longer does. Now it only logs a few requests and nothing else.

Here's the script:

// ==UserScript==
// @name         MyScript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://www.duolingo.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=duolingo.com
// @grant        GM_log
// ==/UserScript==

(function(send, open) {
    'use strict';

    console.log('RUNNING');

    XMLHttpRequest.prototype.send = async function(body) {
        console.log('send() called on', this.url);
        send.apply(this, [body]);
    };

    XMLHttpRequest.prototype.open = function(method, url) {
        console.log('open() called on', url);
        this.url = url;
        open.apply(this, arguments);
    };

})(XMLHttpRequest.prototype.send, XMLHttpRequest.prototype.open);

And here are the logs:

RUNNING
open() called on https://d35aaqx5ub95lt.cloudfront.net/sounds/0a27c1ee63dd220647e8410a0029aed2.mp3
send() called on https://d35aaqx5ub95lt.cloudfront.net/sounds/0a27c1ee63dd220647e8410a0029aed2.mp3
open() called on https://api.rollbar.com:443/api/1/item/
send() called on https://api.rollbar.com:443/api/1/item/
open() called on https://excess.duolingo.com/batch
send() called on https://excess.duolingo.com/batch
open() called on https://excess.duolingo.com/batch
send() called on https://excess.duolingo.com/batch
open() called on https://excess.duolingo.com/batch
send() called on https://excess.duolingo.com/batch
open() called on https://excess.duolingo.com/batch
send() called on https://excess.duolingo.com/batch

I know by inspecting the network tab that there are certain requests that are supposed to get intercepted but don't, for instance the https://www.duolingo.com/YYYY-MM-DD/sessions request, which I can see in the network tab but doesn't get logged to the console.

The match pattern is obviously correct (otherwise none of the logs would be showing), and I know for a fact the script used to work.

Adding @run-at document-start in the metadata improves things slightly, allowing me to see the logs for more requests, but still not nearly for all of them.

I've also tried overriding window.fetch as shown below, but that way none of the URLs would get logged:

(function() {
    'use strict';

    console.log('SCRIPT IS RUNNING');

    const originalFetch = window.fetch;

    window.fetch = async function(request, options) {
        console.log(request.url);
        return originalFetch.apply(this, arguments);
    };
})();
chocojunkie
  • 479
  • 2
  • 8
  • 14
  • Perhaps the request is made early? Try including `// @run-at document-start` in the userscript metadata. – double-beep Jun 28 '23 at 12:00
  • @double-beep yes, I have tried this as well. It improves slightly (I see a couple more requests), but still not solved completely. – chocojunkie Jun 28 '23 at 12:07
  • Try: [Intercept `fetch()` API requests and responses in JavaScript](https://stackoverflow.com/q/45425169) as the request to `/date/sessions` is a `fetch`, not an `xhr` request. – double-beep Jun 28 '23 at 12:30
  • Just tried this, but it didn't work. I'm pretty sure this is the same as what I have at the end of my answer. I'm not sure how you concluded that `/sessions` is a fetch, but one of its headers in the network tab reads `X-Requested-With: XMLHttpRequest`. Although I'm no expert as to what this means. – chocojunkie Jun 28 '23 at 12:43
  • @double-beep UPDATE: tried it again but with `unsafeWindow` instead of `window`, and it seems to log out everything now – chocojunkie Jun 28 '23 at 12:47
  • Inspect the initiator of that request in devtools and see how it's made by the site. – wOxxOm Jun 28 '23 at 13:02

0 Answers0