Skip to content

[MV3] All GM_xmlhttpRequest requests are serialized #2215

@derjanb

Description

@derjanb

Expected Behavior

GM_xmlhttpRequest requests are made in parallel

Actual Behavior

requests run serialized (until response headers are received)

Specifications

  • Chromium: any
  • TM: 5.3+

Explanation

In order to fix #2179 Tampermonkey needs to register a DNR rule for every request. Since those header modifications are not preserved over HTTP redirects like headers set via fetch, Tampermonkey needs to match all requests, but therefore can't run more than one at once. In my opinion this is a Chrome bug.

Workaround

Add the following to your script (Tampermonkey 5.3.2+, Tampermonkey BETA 5.3.6216+).

// @require      https://raw.githubusercontent.com/Tampermonkey/utils/refs/heads/main/requires/gh_2215_make_GM_xhr_more_parallel_again.js

Drawbacks:

  • no progress events
  • 401 responses (basic auth, ...) are not handled

Script

// ==UserScript==
// @name         Non-parallel GM_xhr
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://example.com/*
// @grant        GM_xmlhttpRequest
// @grant        GM.xmlHttpRequest
// @connect      httpbin.org
// ==/UserScript==

console.log('Dummy request started');

GM.xmlHttpRequest({
    method:   "GET",
    url:      'https://httpbin.org/delay/5000',
})
.then(() => {
    console.log('Dummy request finished');
})

GM_xmlhttpRequest({
    method: 'GET',
    url: 'https://httpbin.org/redirect-to?url=https://httpbin.org/headers',
    responseType: 'arraybuffer',
    headers: {
        'user-agent': 'TM',
        'foo': 'bar'
    },
    onreadystatechange: function(event) {
        console.log(`Ready state: ${event.readyState}, status ${event.status}`);
    },
    onprogress: function(event) {
        if (event.lengthComputable) {
            console.log(`Downloading: ${event.loaded}/${event.total}`);
        }
    },
    onload: function(res) {
        console.log('Download finish');
        console.log(res);
        console.log(res.responseText);
    },
    onerror: function(res) {
        console.log('Can\'t load URL');
    }
});

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions