Troubleshooting (Script Authors)

From GreaseSpot Wiki
Revision as of 11:20, 3 November 2017 by Arantius (talk | contribs) (Update for 4.0)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

If your problem is not listed, try Getting Help.

Variables change before a GM_xmlhttpRequest or setTimeout callback runs

Problem example:

for (var i = document.links.length - 1; i >= 0; --i) {
  var link = document.links[i];
  
  GM.xmlHttpRequest({
    method: "GET",
    url: "http://example.com/lookup?url=" + link.href,
    onload: function(result) {
      link.href = result.responseText;
    }
  });
}

The request is asynchronous, meaning the rest of the code doesn't wait for it to complete. The for keeps running as the request loads. When the request for the first link on the page completes and the onload callback function runs, the link variable might point to a different link altogether, typically the last one (since the for loop completes much quicker than the HTTP requests).

One solution is to pass those values that you want unchanged into a function surrounding the request, as arguments. Then they will be in a different scope, and will no longer be changed from the outside.

Solution example with named function:

function do_it(link_inside) {
  GM_xmlhttpRequest({
    method: "GET",
    url: "http://example.com/lookup?url=" + link_inside.href,
    onload: function(result) {
      link_inside.href = result.responseText;
    }
  });
}
  
for (var i = document.links.length - 1; i >= 0; --i) {
  var link = document.links[i];
  do_it(link);
}

Solution example with anonymous function:

for (var i = document.links.length - 1; i >= 0; --i) {
  var link = document.links[i];
  
  (function (link_inside) {
    GM_xmlhttpRequest({
      method: "GET",
      url: "http://example.com/lookup?url=" + link_inside.href,
      onload: function(result) {
        link_inside.href = result.responseText;
      }
    });  
  })(link);
}

Solution example with iteration in the "onload" function. Note that this processes each element one by one.

(function getNext(i) {
  var link = document.links[i];
  GM_xmlhttpRequest({
    method: "GET",
    url: "http://example.com/lookup?url=" + link.href,
    onload: function(result) {
      link.href = result.responseText;
      if (--i >= 0) {
        getNext(i);
      }
    }
  });
})(document.links.length - 1);

Form POST data

When using GM.xmlHttpRequest to POST form data, remember to add the Content-Type parameter:

GM_xmlhttpRequest({
  method: "POST",
  url: myurl,
  headers: {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  data: mydata,
  onload: function(res) { /* Some code */ }
});

Character set

Various issues can arise when working in the wrong character set. In general, writers are advised to use the standard utf-8 format, which isn't supported in the latest version of Windows Notepad. Other workarounds include using JavaScript to parse characters which would otherwise be invalid in other formats, from integer values.

var values = [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33];
alert(String.fromCharCode.apply(String, values));