Skip to content

Instantly share code, notes, and snippets.

@monperrus monperrus/GM_XHR.js

Last active May 25, 2020
Embed
What would you like to do?
allows using all Jquery AJAX methods in Greasemonkey
// allows using all Jquery AJAX methods in Greasemonkey
// inspired from http://ryangreenberg.com/archives/2010/03/greasemonkey_jquery.php
// works with JQuery 1.5
// (c) 2011 Martin Monperrus
// (c) 2010 Ryan Greenberg
//
// Usage:
// $.ajax({
// url: '/p/',
// xhr: function(){return new GM_XHR();},
// type: 'POST',
// success: function(val){
// ....
// }
// });
function GM_XHR() {
this.type = null;
this.url = null;
this.async = null;
this.username = null;
this.password = null;
this.status = null;
this.headers = {};
this.readyState = null;
this.abort = function() {
this.readyState = 0;
};
this.getAllResponseHeaders = function(name) {
if (this.readyState!=4) return "";
return this.responseHeaders;
};
this.getResponseHeader = function(name) {
var regexp = new RegExp('^'+name+': (.*)$','im');
var match = regexp.exec(this.responseHeaders);
if (match) { return match[1]; }
return '';
};
this.open = function(type, url, async, username, password) {
this.type = type ? type : null;
this.url = url ? url : null;
this.async = async ? async : null;
this.username = username ? username : null;
this.password = password ? password : null;
this.readyState = 1;
};
this.setRequestHeader = function(name, value) {
this.headers[name] = value;
};
this.send = function(data) {
this.data = data;
var that = this;
// http://wiki.greasespot.net/GM_xmlhttpRequest
GM_xmlhttpRequest({
method: this.type,
url: this.url,
headers: this.headers,
data: this.data,
onload: function(rsp) {
// Populate wrapper object with returned data
// including the Greasemonkey specific "responseHeaders"
for (var k in rsp) {
that[k] = rsp[k];
}
// now we call onreadystatechange
that.onreadystatechange();
},
onerror: function(rsp) {
for (var k in rsp) {
that[k] = rsp[k];
}
}
});
};
};
@Acorn-zz

This comment has been minimized.

Copy link

Acorn-zz commented Jul 2, 2011

Really useful script, thanks!

@Acorn-zz

This comment has been minimized.

Copy link

Acorn-zz commented Jul 2, 2011

Hmm, do you know if there's a way to get the finalUrl property in the response as defined here: http://wiki.greasespot.net/GM_xmlhttpRequest ?

I get it when I use GM_xmlhttpRequest directly, but not when using it through jQuery.

@monperrus

This comment has been minimized.

Copy link
Owner Author

monperrus commented Jul 4, 2011

Hi, have you tried xhr.finalUrl? (normally all properties are copied from GM_xmlhttpRequest).
--Martin

@apankrat

This comment has been minimized.

Copy link

apankrat commented Feb 20, 2012

Thanks, Martin.

@damoclark

This comment has been minimized.

Copy link

damoclark commented May 22, 2014

Hi Martin,

Thanks for sharing this snippet - it has been very useful.

I seem to have stumbled upon a bug in the onerror handler. Testing, if making an ajax call to a web server that is shutdown, it should pretty much get an immediate error response, but using GM_XHR with jquery does not. I think the that.onreadystatechange(); method needs to also be called at the end of the onerror function. I've just done a very quick patch rather than the whole fork and issue a pull request. See what you think and whether it should be added to your class.

Cheers,
Damien.

diff -u GM_XHR.js GM_XHR2.js
--- GM_XHR.js 2014-05-22 11:49:24.000000000 +1000
+++ ../../999065/GM_XHR.js 2014-05-22 11:44:08.000000000 +1000
@@ -74,7 +74,9 @@
for (var k in rsp) {
that[k] = rsp[k];
}

  •            // now we call onreadystatechange
    
  •            that.onreadystatechange();
         }
     });
    
    };
    -};
    \ No newline at end of file
    +};
@ApacheTech

This comment has been minimized.

Copy link

ApacheTech commented May 13, 2016

I think changes to jQuery may have broken this, since it was created.

The error message "that.onreadystatechange is not a function", is all I can get out of it.

Is there an updated version, anywhere on the net? Or, ideas for a fix?

@galeksandrp

This comment has been minimized.

Copy link

galeksandrp commented May 20, 2016

Yes.

From 2385c1267dc966da27107d23f7d9870420126297 Mon Sep 17 00:00:00 2001
From: Alexander Georgievskiy <galeksandrp@gmail.com>
Date: Wed, 25 May 2016 23:49:10 +0300
Subject: [PATCH]


---
 GM_XHR.js | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/GM_XHR.js b/GM_XHR.js
index df79732..d3d9b6e 100644
--- a/GM_XHR.js
+++ b/GM_XHR.js
@@ -61,6 +61,7 @@ function GM_XHR() {
             url: this.url,
             headers: this.headers,
             data: this.data,
+            responseType: this.responseType,
             onload: function(rsp) {
                 // Populate wrapper object with returned data
                 // including the Greasemonkey specific "responseHeaders"
@@ -68,12 +69,14 @@ function GM_XHR() {
                     that[k] = rsp[k];
                 }
                 // now we call onreadystatechange
-                that.onreadystatechange();
+                if (that.onload) that.onload(); else that.onreadystatechange();
             },
             onerror: function(rsp) {
                 for (var k in rsp) {
                     that[k] = rsp[k];
                 }
+                // now we call onreadystatechange
+                if (that.onerror) that.onerror(); else that.onreadystatechange();
             }
         });
     };
-- 
2.8.3.windows.1

@reason211

This comment has been minimized.

Copy link

reason211 commented Jan 2, 2019

Replace
for (k in rsp) { that[k] = rsp[k]; }
To
for (var k in Object.getOwnPropertyNames(rsp)) { that[Object.getOwnPropertyNames(rsp)[k]] = rsp[Object.getOwnPropertyNames(rsp)[k]]; }

It's work for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.