What Is the GM_xmlhttpRequest API in Userscripts?
The GM_xmlhttpRequest API is a specialized network
function provided by browser userscript managers like Tampermonkey,
Violentmonkey, and Greasemonkey. It enables custom JavaScript
userscripts to execute cross-origin HTTP requests, bypassing the
browser’s native Same-Origin Policy (SOP). This article explores what
GM_xmlhttpRequest is, why it is necessary for advanced
browser customization, its core parameters, and how to use it securely
in your scripts.
The Core Problem: The Same-Origin Policy
When writing standard web scripts, browsers enforce the Same-Origin Policy. This security mechanism restricts web pages from making network requests to a domain different from the one currently serving the page.
If a userscript running on example.com attempts to fetch
data from an external API at api.thirdparty.com using
native fetch() or standard XMLHttpRequest, the
browser will typically block the response due to CORS (Cross-Origin
Resource Sharing) restrictions.
How GM_xmlhttpRequest Solves the Problem
Because userscript managers operate with higher privileges than
standard web pages, they can expose extended APIs to user scripts.
GM_xmlhttpRequest leverages the extension background
process to make network calls, allowing your script to:
- Bypass CORS constraints: Request data from any public API or website regardless of the host page’s origin.
- Send custom headers: Modify headers such as
User-Agent,Referer, or custom authentication tokens that web pages cannot normally alter. - Access third-party services: Fetch data like price comparisons, weather reports, or external database records to enrich the host website’s user interface.
Basic Syntax and Structure
To use GM_xmlhttpRequest, you must first request
permission in the userscript metadata block using the
@grant header, along with @connect directives
specifying allowed domains.
// ==UserScript==
// @name External Data Fetcher
// @namespace http://tampermonkey.net/
// @version 1.0
// @match https://example.com/*
// @grant GM_xmlhttpRequest
// @connect api.github.com
// ==UserScript==
GM_xmlhttpRequest({
method: "GET",
url: "https://api.github.com/zen",
headers: {
"Accept": "text/plain"
},
onload: function(response) {
console.log("GitHub Zen:", response.responseText);
},
onerror: function(error) {
console.error("Request failed:", error);
}
});Key Configuration Options
The function accepts a single configuration object containing parameters similar to standard network APIs:
method: The HTTP method (GET,POST,PUT,DELETE, etc.).url: The destination URL for the network request.headers: An object containing key-value pairs for request HTTP headers.data: The request body string (used primarily forPOSTorPUTrequests).timeout: Time in milliseconds before the request automatically aborts.onload: A callback function executed when the request completes successfully.onerror: A callback triggered if the network request encounters a fatal error.ontimeout: A callback triggered if the request exceeds the specified timeout threshold.
Security Best Practices
Because GM_xmlhttpRequest elevates network capabilities,
improper usage can introduce security vulnerabilities:
- Restrict origins with
@connect: Always specify explicit domain patterns in your metadata header rather than using wildcards (*) when possible. - Sanitize external data: Treat all data returned via
GM_xmlhttpRequestas untrusted. Never inject raw HTML directly into the page DOM usinginnerHTMLwithout sanitization, as this can lead to Cross-Site Scripting (XSS) vulnerabilities.