firefoxfirefox-addonfirefox-addon-sdkprotocol-handler

Using a custom protocol with XMLHttpRequest in a Firefox add-on


I've created an addon that defines a custom protocol; blabla:

for now blabla:*** just redirects to google.com - this works fine.

However, I want to execute a XMLHttpRequest to get the real URL it should redirect to. But from the moment I add this 1 line (nothing else yet), the addon stops functioning:

var request = new XMLHttpRequest();

Are there special rules for custom protocol addons that I'm not aware of? (such as no xmlhttprequests)? Is there no way around this?

var wheretogo = WhereToGo(resource);
var uri = ioservice.newURI(wheretogo, null, null);
var channel = ioservice.newChannelFromURI(uri, null).QueryInterface(Ci.nsIHttpChannel);


function  WhereToGo(fres) {       
  //  var request = new XMLHttpRequest();

  return 'http://google.com';
}

EDIT:

I'm now using this code :

    var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] .createInstance(Components.interfaces.nsIXMLHttpRequest);
    request.open("GET", "http://localhost:5000/?request=" + fres, false); //synchronous
    request.setRequestHeader("Content-Type", "application/json");
    request.send(null);

But getting this error:

[Exception... "Failure"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: file:///Users/wesley/Desktop/ProtocolFx/components/Protocol.js :: WhereToGo :: line 51"  data: no]

Any idea why this doesn't work? (Is it because of the port number?) I thought XMLHttpRequest was allowed to be cross domain in firefox addons?

When I change it to fetch http://google.com/ instead of localhost, I get a response.status of 0 and a response.responseText of ''


Solution

  • The XMLHttpRequest constructor is only defined in the context of DOM windows. If your code is running in a different context (like an SDK module which is essentially a sandbox) this constructor will not be defined and you have to create an instance via XPCOM:

    var {Cc, Ci} = require("chrome");
    var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
                    .createInstance(Ci.nsIXMLHttpRequest);
    

    For reference: chrome authority, Using XMLHttpRequest from JavaScript modules / XPCOM components.

    Note that the usual recommendation for SDK-based extensions is using the request module which has the advantage of automatically canceling your request if the extension is disabled/uninstalled. There is also the low-level net/xhr module providing an interface that is similar to the native XMLHttpRequest and that will also cancel requests automatically if needed. However, from all I know neither of the two will give access to the XMLHttpRequest.channel property that is required to find the "real" URL of the request.