Troubleshooting (Script Authors): Difference between revisions

From GreaseSpot Wiki
Jump to navigationJump to search
m (→‎Form POST data: Prime reason to not wik format code...removed extra ''s)
m (dewikifying article/correcting GMXHR POST method to remove Fair example/Removal of class attribute on pre tag/Normalized to GMW standard... think we lost Photodeus to correct these latest additions)
Line 18: Line 18:
Problem example:
Problem example:


  for (var i=0; i < document.links.length; i++) {
<code><pre>
    var '''link''' = document.links[i];
for (var i = 0; i < document.links.length; i++) {
  var link = document.links[i];
    
    
    GM_xmlhttpRequest({
  GM_xmlhttpRequest({
      method: "GET",
    method:"GET",
      url: '&#104;ttp://example.com/lookup?url=' + link.href,
    url:"&#104;ttp://example.com/lookup?url=" + link.href,
      onload: function(result) {
    onload:function(result) {
        '''link'''.href = result.responseText;
      link.href = result.responseText;
      }
    }
    });
  });
  }
}
</pre></code>


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


Solution example with named function:
Solution example with named function:
<pre class="badexample">
<code><pre>
  function do_it('''link_inside''') {
function do_it(link_inside) {
    GM_xmlhttpRequest({
  GM_xmlhttpRequest({
      method: "GET",
    method:"GET",
      url: '&#104;ttp://example.com/lookup?url=' + '''link_inside'''.href,
    url:"&#104;ttp://example.com/lookup?url=" + link_inside.href,
      onload: function(result) {
    onload:function(result) {
        '''link_inside'''.href = result.responseText;
      link_inside.href = result.responseText;
      }
    }
    });
  });
  }
}
    
    
  for (var i=0; i < document.links.length; i++) {
for (var i = 0; i < document.links.length; i++) {
    var '''link''' = document.links[i];
  var link = document.links[i];
    
    
    do_it('''link''');
  do_it(link);
  }
}
</pre>
</pre></code>
Solution example with anonymous function:
Solution example with anonymous function:


  for (var i=0; i < document.links.length; i++) {
<code><pre>
    var link = document.links[i];
for (var i = 0; i < document.links.length; i++) {
  var link = document.links[i];
    
    
    (function ('''link_inside''') {
  (function (link_inside) {
    
    
      GM_xmlhttpRequest({
    GM_xmlhttpRequest({
        method: "GET",
      method:"GET",
        url: '&#104;ttp://example.com/lookup?url=' + '''link_inside'''.href,
      url:"&#104;ttp://example.com/lookup?url=" + link_inside.href,
        onload: function(result) {
      onload:function(result) {
          link_inside.href = result.responseText;
        link_inside.href = result.responseText;
        }
      }
      });
    });
    
    
    })('''link''');
  })(link);
  }
}
</pre></code>


== Component not Available errors ==
== Component not Available errors ==
Line 78: Line 82:
When using [[GM_xmlhttpRequest]] to POST form data, remember to add the '''Content-Type''' parameter:
When using [[GM_xmlhttpRequest]] to POST form data, remember to add the '''Content-Type''' parameter:


{{Fair example|<nowiki>GM_xmlhttpRequest({
<code><pre>
   method: 'POST' : 'GET',
GM_xmlhttpRequest({
   url: myurl,
   method:"POST",
   headers: {
   url:myurl,
     'User-Agent': window.navigator.userAgent,
   headers:{
     'Content-Type': 'application/x-www-form-urlencoded'
     "User-Agent":navigator.userAgent,
     "Content-Type":"application/x-www-form-urlencoded"
   },
   },
   data: mydata,
   data:mydata,
   onload: function(res) { ... }
   onload:function(res) { /* Some code */ }
});
});
</nowiki>}}
</pre></code>


== Links ==
== Links ==
Line 96: Line 101:
* http://dunck.us/collab/GreaseMonkeyUserScripts#head-4ac4d1e80f8bbd66bf4f1fbea77ea2390b6a2870
* http://dunck.us/collab/GreaseMonkeyUserScripts#head-4ac4d1e80f8bbd66bf4f1fbea77ea2390b6a2870
* http://www.brockman.se/writing/method-references.html.utf8
* http://www.brockman.se/writing/method-references.html.utf8
{{stub}}

Revision as of 06:18, 1 May 2009

The article Avoid Common Pitfalls in Greasemonkey covers some of the most common problems people come across when writing user scripts.

If your problem is not listed, please ask on the mailing list.

Changes don't take effect when editing a script

You may be editing your original copy of the script, not the installed copy. Once you create and install a script, you need to follow these steps to make sure you're editing the installed, active copy.

Also, changing the include and exclude rules in the metadata block of the installed script does not do anything, as the script metadata is only accessed during installation. The script must be re-installed (or config.xml edited manually) for these changes to take.

Note: You can change the include and exclude rules in the Manage User Scripts window and those changes will take effect.

Variables change before a GM_xmlhttpRequest or setTimeout callback runs

Problem example:

for (var i = 0; i < document.links.length; 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 = 0; i < document.links.length; i++) {
  var link = document.links[i];
  
  do_it(link);
}

Solution example with anonymous function:

for (var i = 0; i < document.links.length; 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);
}

Component not Available errors

These are usually caused by attempting to access an element's event handlers (onclick, onkeydown, etc.) directly, rather than through addEventListener. GreaseMonkey 0.5 and above require the use of addEventListener. For details, see XPCNativeWrapper.

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:{
    "User-Agent":navigator.userAgent,
    "Content-Type":"application/x-www-form-urlencoded"
  },
  data:mydata,
  onload:function(res) { /* Some code */ }
});

Links