views:

4717

answers:

5

I'm trying to get the sample code from Mozilla that consumes a REST web service to work under Firefox 3.0.10. The following code does NOT work in Firefox but does in IE 8!

  1. Why is this not working?
  2. Does IE 8 have support for XMLHttpRequest? Most examples I've seen use the ActiveX allocation. What should I be doing? XMLHttpRequest seems more standardized.

Sample:

var req = new XMLHttpRequest();
req.open('GET', 'http://localhost/myRESTfulService/resource', false);    // throws 'undefined' exception
req.send(null);
if(req.status == 0)
  dump(req.responseText);

The open statement is throwing an exception with the description 'undefined'. This is strange as I allocate the req object, am running it in Firefox, and checked to make sure it is defined before calling open (which it says it is of type 'object').

I've also tried the asynchronous version of this with no luck.

EDIT 2: Below is my most recent code:

function createRequestObject() {
    if( window.XMLHttpRequest ) {
     return new XMLHttpRequest();
    }
    else if( window.ActiveXObject ) {
     return new ActiveXObject( "Microsoft.XMLHTTP" );
    }

    return null;
}

function handleResponse( req ) {
    document.writeln( "Handling response..." );   // NEVER GETS CALLED
    if( req.readyState == 0 ) {
     document.writeln( "UNITIALIZED" );
    }
    else if( req.readyState == 1 ) {
     document.writeln( "LOADING" );
    }
    else if( req.readyState == 2 ) {
     document.writeln( "LOADED" );
    }
    else if( req.readyState == 3 ) {
     document.writeln( "INTERACTIVE" ); 
    }
    else if( req.readyState == 4 ) {
     document.writeln( "COMPLETE" );
     if( req.status == 200 ) {
      document.writeln( "SUCCESS" );
     }
    }
}

document.writeln( "" );
var req = createRequestObject();

try {
    document.writeln( "Opening service..." );
    req.onreadystatechange = function() { handleResponse( req ); };
    req.open('POST', 'http://localhost/test/test2.txt', true);  // WORKS IN IE8 & NOT FIREFOX


    document.writeln( "Sending service request..." );
    req.send('');

    document.writeln( "Done" );
}
catch( err ) {
    document.writeln( "ERROR: " + err.description );
}

EDIT 3: Alright, I reworked this in jQuery. jQuery works great in IE but it throws 'Undefined' when running from Firefox. I double checked and 'Enable JavaScript' is turned on in Firefox - seems to work fine in all other web pages. Below is the jQuery code:

function handleResponse( resp ) {
    alert( "Name: " + resp.Name );
    alert( "URL: " + resp.URL );
}

$(document).ready( function() {
    $("a").click( function(event) {

     try {
      $.get( "http://localhost/services/ezekielservices/configservice/ezekielservices.svc/test", 
          "{}",
          function(data) { handleResponse( data ); },
          "json" );
     } 
     catch( err ) {
      alert("'$.get' threw an exception: " + err.description);
     }

     event.preventDefault();
    });
} );    // End 'ready' check

Summary of Solution:

Alright, web lesson 101. My problem was indeed cross-domain. I was viewing my site unpublished (just on the file system) which was hitting a published service. When I published my site under the same domain it worked.

Which also brings up an important distinction between IE and Firefox. When IE experiences this scenario, it prompts the user whether or not they accept the cross-domain call. Firefox throws an exception. While I'm fine with an exception, a more descriptive one would have been helpful.

Thanks for all those who helped me.

+4  A: 

unless 'http://www.mozilla.org/' is the domain from which this request originates, this wont work because of same origin policy

edit: Ok, a good status is 200, not 0.

see http://dogself.com/telluriumTest/ and click on "stackoverflow test". its using your code and working.

specifically this code:

function test(){
    var req = new XMLHttpRequest();
    req.open('GET', 'index2.htm', false);    
    req.send(null);
    if(req.status == 200)
    alert("got some stuff back:"+req.responseText);
}
mkoryak
Okay, I see what you are saying. I've tried hitting a local file and a local web service, and it doesn't work either. It works in IE8 locally but fails in Firefox.
j0rd4n
check my latest edit. your code is working for me
mkoryak
either way, why dont you save yourself a few hours of head aches and use jquery?
mkoryak
Good question. I'm new to JavaScript development. Does jQuery make this easier?
j0rd4n
yes, if you use jquery everything will work. check out the tutorial for using ajax GET: http://docs.jquery.com/Ajax/jQuery.get#urldatacallbacktype
mkoryak
ok, i saw your modified code. i have copied it to my domain with very slight modifications. it works in firefox 3. if it doesnt work for you, then your firefox 3 is broken. check it out:http://dogself.com/telluriumTest/test.htm let me know if it still doesnt work.
mkoryak
Man, this is strange. I tried your code. It works when I view it in Firefox from *your* site. If I take it locally and change the file name to a local file hosted on localhost, it works only in IE and returns 'undefined' in Firefox.
j0rd4n
BTW, it fails on other machines as well...(in Firefox and not IE8).
j0rd4n
i know what is wrong with your code.. you must have other code, that is breaking this. have you tried a minimal testcase with JUST the code above? if that testcase works, slows start adding your code back in until it breaks etc.
mkoryak
Well, I tried running the simple HTML file you put together and it failed. For instance, if I take your code, change the 'POST' to a 'GET', it returns the contents of the htm file in IE. If I run the exact same thing in Firefox it errors out.
j0rd4n
you should try creating a new firefox profile using this info: http://kb.mozillazine.org/Profile_Manager and trying it there. thats about as close as you can get to reinstalling firefox without doing so. On the other hand, if you can run it on my site, but not locally, maybe the problem isnt with your firefox, but something else.
mkoryak
I'll try it on my home machine and see if I still have the problem.
j0rd4n
You're first suggestion was correct. It was a cross-domain issue and how firefox handles those kinds of errors. See my summary in the OP.
j0rd4n
+1  A: 

I highly recommend the asynchronous way to do it, one function kicks off the request and another function handles the response.

function makeRequest() 
{
   var httpRequest;
   if (window.XMLHttpRequest) // firefox etc 
   {
       httpRequest = new XMLHttpRequest();
   } else if (window.ActiveXObject) { // ie
       httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
   }
   httpRequest.onreadystatechange = function(){handleResponse(httpRequest)};
   httpRequest.open('POST','http://localhost/test/test2.txt',true);
   httpRequest.send('');
}


function handleResponse(request)
{
    if(request.readyState == 4) {
        if(request.status == 200) {
        // handling code here
            // request.responseText is the string returned
        }
    }
}

This is the basic format for ajax calls we use where I work, this should work the same for Firefox, IE, and Safari.

Side note: do you have firebug? its a great resource for troubleshooting javascript.

EDIT: Try this code instead:

<html>
<head>
<script>
function out(outStr) // cheap and dirty output function
{
    document.getElementById("out").innerHTML += "<br>" + outStr;
}

function handleResponse(req) {
    if( req.readyState == 0 ) {
        out("UNITIALIZED");
    }
    else if( req.readyState == 1 ) {
        out("LOADING");
    }
    else if( req.readyState == 2 ) {
        out("LOADED");
    }
    else if( req.readyState == 3 ) {
        out("INTERACTIVE"); 
    }
    else if( req.readyState == 4 ) {
        out("COMPLETE");
        if( req.status == 200 ) {
            out(req.responseText);
        }
    }
}

function createRequestObject() {
    var req = null 
    if(window.XMLHttpRequest) {
        req = new XMLHttpRequest();
    } else if(window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return req;
}

function makeRequest()
{
    var req = createRequestObject();

    try {
        out("Opening service...");
        req.onreadystatechange = function() { handleResponse( req ); };
        req.open('POST', 'http://localhost/test/test2.txt', true);  // WORKS IN IE8 & NOT FIREFOX


        out("Sending service request...");
        req.send('');

        out("Done");
    }
    catch( err ) {
        out("ERROR: " + err.description);
    }
}
</script>
</head>
<body>
<div onclick="makeRequest();">test<br></div>
<div id="out">Output Here</div>
</body>
</html>

point: http://localhost/test/test2.txt to an existing file on your server.

Not sure exactly what is going wrong with your code, but it is writing straight to document which appears to be hosing all of the code already written there. in this version I am writing to a div instead.

Jim Ford
I've tried this exact code. Works like a champ in IE but not Firefox. I'm going to use Firebug real quick and see what is going on...
j0rd4n
See my most recent code above...
j0rd4n
This is VERY bizarre. Your updated code works great in IE 8 but I get "ERROR: undefined" in Firefox. I tried my original solution but changed it to use jQuery instead ($.get). The jQuery works in IE but throws an undefined error in Firefox...this is spooky.
j0rd4n
BTW, it fails on other machines as well...(in Firefox and not IE8).
j0rd4n
+1  A: 

Hi, not sure what's going on here either, but just wanted you all to know that someone from Mozilla documentation is watching this to be ready to tweak the docs if it turns out to be necessary once this is figured out.

Awesome! Anything to help spread the fox. Are you able reproduce the issue?
j0rd4n
It works fine in the nightly build of Firefox 3.5 I'm running here.
It's also working fine for me in Firefox 3.0.3 (the last version of 3.0.x I have on hand without doing an upgrade).
I'll try it on my home machine and see if I still have the problem.
j0rd4n
Figured it out...see my summary in the original post. It was how Firefox handles cross-domain issues.
j0rd4n
+1  A: 

dont use onreadystatechange when sending synchronous request ('false'), put the handler right after the send() function. It seems FF doesnt execute the onreadystatechange function if request is synchronous.

http://support.mozilla.com/tiki-view_forum_thread.php?locale=ca&amp;comments_parentId=124952&amp;forumId=1

sendfreesms
A: 

Even I had same problem and it was silly mistake which we do not focus on the code was working fine in IE but had problems in Chrome and Firefox

Initilly we used Type="submit" instead of type="button" though the we did not have any functionality problems like updating the tables but we were getting HTTP: error 0 in the alert box when I alerted req.responseText Using the below code solved my problem input type="button" name="btnEdit5" id="btnEdit5" value="Confirm" onClick="show_confirm()"

Dily