0

The following code creates an alert with the content undefined:

// ==UserScript==
// @name     Unnamed Script 188765
// @version  1
// @grant    GM.xmlHttpRequest
// @include  http*//markasoftware.com/*
// ==/UserScript==

alert(typeof GM.xmlHttpRequest({
  url: 'https://google.com',
  synchronous: true,
  method: 'GET',
}));

Based on the documentation, I would expect the synchronous option to make the call return a response object. Yet, it acts the same way as an async call would; the onload handler still works. Was the synchronous option disabled? Is there some other way to make a cross-origin request synchronously?

markasoftware
  • 12,292
  • 8
  • 41
  • 69
  • it will just block ui while this request is sent and a response is received. You can check this https://stackoverflow.com/questions/14077906/synchronous-cross-domain-request. – Mahendra Pratap Aug 26 '19 at 16:51
  • The documentation says **more data will be available in the return value.** But it doesn't say what that information will be, and there are no examples. – Barmar Aug 26 '19 at 16:51
  • @Barmar if there was any data whatsoever in the return value, it's type would not be `undefined`. – markasoftware Aug 26 '19 at 16:59
  • 1
    I think the line saying that more data would be available is just a mistake in the doc. – Barmar Aug 26 '19 at 17:00
  • 1
    You should still be able to make the request synchronously. The `onload` function can set variables in an outer scope and they should be available after the function returns. – Barmar Aug 26 '19 at 17:02
  • @Barmar you're right! It's too bad the wiki doesn't allow public editors. If you want to post that comment as an answer I'll accept it. – markasoftware Aug 26 '19 at 17:46
  • Just curious: what happens if the `onload` function returns something? Maybe that gets returned by `xmlHttpRequest`. – Barmar Aug 26 '19 at 17:52
  • 1
    @Barmar Nope, it always returns undefined. – markasoftware Aug 26 '19 at 18:02
  • AFAIK there should be no way to actually perform GMXHR synchronously in WebExtensions-based Greasemonkey because it involves a cross-process communication which is always asynchronous. Well theoretically maybe you can force Firefox to use just one process though. – wOxxOm Aug 26 '19 at 19:00

1 Answers1

3

The documentation that says that the return value will be different when using synchronous mode is wrong. Just set a variable that you use outside of the onload function.

let returnData;
GM.xmlHttpRequest({
  url: 'https://google.com',
  synchronous: true,
  method: 'GET',
  onload: function(response) {
    returnData = response;
  }
}));
alert(returnData);
Barmar
  • 741,623
  • 53
  • 500
  • 612