tags:

views:

32

answers:

2

I have a page that uses the following to submit a AJAX request:

function oc()
{
  jQuery.get(
    "http://somewhere.com:5001/ajax/options/",
    jQuery('#selectform').serialize(),
    function(data,statusm,xml){
      // I got nothing!!!
      return;
    }
  );
}

If I make the request manual from the address bar, things work. And when I make the request from the JS I can see via logging that the server side is working correctly, but in the call back, I can't seem to get the contents of the reply.

What am I going wrong?

+3  A: 

What you're likely seeing is the same-origin policy kicking in. This is a browser security feature to prevent cross-site scripting attacks, and accessing even the same domain/host on a different port counts as being on a "different domain" as far as the policy goes. The example table on Wikipedia does an excellent job of showing what is/isn't allowed.

You can additionally test this by using the --disable-web-security command line switch in Chrome, then your script should work...it's not a solution, just helps confirm the problem.

In short, you need to make requests to the same domain or host and port, otherwise it'll be blocked. The exception to this rule is using JSONP, which is used mostly for this purpose. You can find some decent examples here and here.

Nick Craver
Nick, he said the server side is working correctly. That wouldn't happen if it's an origin issue.
Matthew Flaschen
@Matthew - You'll see *exactly* this behavior in a same-origin issue, it's not there to protect the server, it's there to protect the client, i.e. blocking the response.
Nick Craver
You can do a blind request other ways (e.g. an image tag), but not with XHR. Try http://jsfiddle.net/Degf7/ with Wireshark open. You'll get an error, and it won't send a request. Note that in some cases the error is masked, so the success function is called with blank data. But the request is never actually sent.
Matthew Flaschen
@Matthew - I just ran a test here to confirm (this is in Chrome 6), the server *does* get hit, and the data response is blank, even though the server did send a response...this is the policy blocking it. My previous comment is accurate, at least in Firefox/Chrome and IE.
Nick Craver
@Matthew - Use firebug or Chrome tools, you'll see the request going out. I have confirmed this by actually setting something up on another domain and hitting it...the request *does* go out, I'm not sure how you're monitoring wireshark, but this is not accurate.
Nick Craver
Oh, crud, now I need to figure out how to dish out static content... :(
BCS
@BCS - Is there a reason this has to be on a different port? :)
Nick Craver
@Nick, I'm sorry, you're absolutely right. I got confused by NoScript.
Matthew Flaschen
@Matthew - Ahhh that makes more sense...but hey you've confirmed it's doing its job :)
Nick Craver
@Nick, The static file up till now has resided in the local file system :)
BCS
@BCS - What URL is the page running from? just `localhost/`, e.g. port 80?
Nick Craver
file:////dir/something.html
BCS
@BCS - Ah yeah that'll be a problem, is this you specifically running it, or a generic client file or....?
Nick Craver
@Nick, it's definitely doing something. ;) The thing is, NoScript now does a lot more than block scripts. The script that did the XHR was running on jsfiddle, which I of course had whitelisted. It didn't occur to me that I had to whitelist example.com, since I wasn't running script from there. But there's an about:config option, `noscript.forbidXHR`. By default, (value 1) it only allows requests to trusted sites. Any others it blocks before being sent. I've changed it to 0 now, so it should match Firefox's default behavior.
Matthew Flaschen
This is just test work, The real thing would be generated so I won't see this problem once I get to that point.
BCS
+1  A: 

Try using an error function with $.ajax.

$.ajax({
  url: "http://somewhere.com:5001/ajax/options/",
  data: jQuery('#selectform').serialize(),
  success: function(data,statusm,xml){
  // I got nothing!!!
  return;
  },
  error: function(XMLHttpRequest, textStatus, errorThrown) {
    // do something
  }
});
Matthew Flaschen