Question

I started learning addon development using addon-sdk. I'm writing a small addon script which display IP address of current webpage.

I used a website which provides JSON data values.
http://dazzlepod.com/ip/stackoverflow.com.json

Now the problem is when I make XMLHttp request to get JSON values it shows 0x80004005 (NS_ERROR_FAILURE)

Message: [Exception... "Failure" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: .... ...... :: httpGet :: line 30" data: no]

Here's my ScriptCode

function getDomainInfo(url) {
    var a = document.createElement('a');
    a.href = url;

    var domain = a.hostname;
    var requestURL = "http://dazzlepod.com/ip/"+domain+".json";
    //alert(requestURL);
    return httpGet(requestURL);
}

function httpGet(theUrl)
{
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            return xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET", theUrl, false );
    xmlhttp.send();    
}

var check = self.port.on("clicked", function(url) {
    var json = getDomainInfo(url);
    //alert(json);
});

Can Anyone explain why this is happening and What should I do?
I'm kind of new to addon development.
Thank You.

GitHUb Link https://github.com/kannojia/show-ip

Was it helpful?

Solution

Ok, I solved the problem. The problem was that you cannot make XMLHttp request to some other domain while residing on some other due to same origin policy .
Therefore when contentScript made XMLHttp request to the server, the browser throws NS_error_failure.

The solution I found is to use Request API of Addon SDK . The Request object is used to make GET, POST, or PUT network requests. The Request object is not subjected to same-origin-policy.
So instead of making Http request from contentScript, I used request API and got the valid response.

The modified code main.js :

var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var data = require("sdk/self").data;
var Request = require("sdk/request").Request;

var url;
var domain_name;
var requestURL;

var showipWidget = widgets.Widget({
    id : "show-ip",
    label : "Display IP Address of current Page",
    contentURL : data.url("lens_icon.png"),
    contentScriptFile : [data.url("click_handler.js"),data.url("jquery-1.8.3.min.js")],
    panel : infoPanel,
    onClick : function() {
        var curtab = tabs.activeTab;
        url = curtab.url;
        this.port.emit('getDomain',url);
    }   
});

showipWidget.port.on("setDomain", function(domain) {
    domain_name=domain;
    getDomainInfo(domain_name);
});

function getDomainInfo(domain) {
    requestURL = "http://dazzlepod.com/ip/"+domain+".json";
    //requestDomainInfo.get();

    Request({
      url: requestURL,
      onComplete: function (response) {
        var out = response.json;
        console.log("Response: "+out.ip);
      }
    }).get();

}

And the Content Script click_handler.js

function getDomain(url) {
    var a = document.createElement('a');
    a.href = url;
    var domain = a.hostname;
    return domain;
}

var check = self.port.on("getDomain", function(url) {
    var domain = getDomain(url);
    self.port.emit("setDomain",domain);
});

All files are on GitHub.
Thank You Everyone for your help.

OTHER TIPS

You're running into a security error because you cant make xmlhttprequest to another domain while on another. Try loading a tab with http://dazzlepod.com as url and then run your code from scratchpad it will work.

If you want cross site then try to use the mozSystem property: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest?redirectlocale=en-US&redirectslug=DOM%2FXMLHttpRequest#XMLHttpRequest%28%29

Ok so you're not getting a security error. The reuest goes through succesfully:

http://dazzlepod.com/ip/stackoverflow.com.json

GET /ip/stackoverflow.com.json HTTP/1.1
Host: dazzlepod.com
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:30.0) Gecko/20100101 Firefox/30.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: null
Connection: keep-alive

HTTP/1.1 200 OK
Server: nginx
Date: Mon, 24 Mar 2014 00:36:37 GMT
Content-Type: application/json
Content-Length: 198
Connection: keep-alive
Content-Encoding: gzip
Expires: Wed, 23 Apr 2014 00:36:36 GMT
Vary: Accept-Encoding
Last-Modified: Mon, 24 Mar 2014 00:36:36 GMT
Cache-Control: max-age=2592000
X-Frame-Options: DENY

i wonder if that x-frame-options: deny has anything to do with whats going on.

anyways you get that ns failur error because of this reason:

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help http://xhr.spec.whatwg.org/ click_handler.js:31

so you have to set third argument on .open to true.

but then still im getting a bunch of no responseXML or responeText or event responeType or respone.

Its weird.

I just changed the code in the click_handler.js and also its weird but console.log doesnt work from here, at least in aurora.

function getDomainInfo(url) {
    var a = document.createElement('a');
    a.href = url;

    var domain = a.hostname;
    var requestURL = "http://dazzlepod.com/ip/"+domain+".json";
    alert(requestURL);
    return httpGet(requestURL);
}

function httpGet(theUrl)
{
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onload = function() {
        alert('onload done ' + '\n' + xmlhttp.readyState + '\n' + xmlhttp.status + '\n' + xmlhttp.responseText + '\n' + xmlhttp.response + '\n' + xmlhttp.responseType + '\n' + xmlhttp.responseXML);
        alert('onload done ' + '\n' + this.readyState + '\n' + this.status + '\n' + this.responseText + '\n' + this.response + '\n' + this.responseType + '\n' + this.responseXML);
    }
    xmlhttp.onreadystatechange=function()
    {
        alert('onreadystatechange' + '\n' + xmlhttp.readyState + '\n' + xmlhttp.status + '\n' + xmlhttp.responseText + '\n' + xmlhttp.response + '\n' + xmlhttp.responseType + '\n' + xmlhttp.responseXML);
            alert('onreadystatechange this ' + '\n' + this.readyState + '\n' + this.status + '\n' + this.responseText + '\n' + this.response + '\n' + this.responseType + '\n' + this.responseXML);
        if (xmlhttp.readyState==4)
        {
            alert('onreadystatechange READYSTE==4' + '\n' + xmlhttp.readyState + '\n' + xmlhttp.status + '\n' + xmlhttp.responseText + '\n' + xmlhttp.response + '\n' + xmlhttp.responseType + '\n' + xmlhttp.responseXML);
            return xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET", theUrl, true );
    alert('xmlhttp = ', xmlhttp);
    xmlhttp.send();    
}

var check = self.port.on("clicked", function(url) {
    alert(window.location);
    var json = getDomainInfo(url);
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top