views:

119

answers:

3

I'm using jQuery's .ajax() to call a server (actually local Django runserver) and get a response.

On the server console, I can see that the JSON request comes in, he proper JSON response is made, and everything looks OK.

But in my browser (tested on Firefox 3.6 and Safari 4.0.4, and I'm using jQuery 1.4.2), it seems the response body is empty (the response code is 200, and the headers otherwise look OK).

Testing the response from the command line, I get the answer I expect.

$ curl http://127.0.0.1:8000/api/answers/answer/1 --data "text=test&user_name=testy&user_location=testyville&site=http%3A%2F%2Flocalhost%3A8888%2Fcs%2Fjavascript_answer_form.html&email_address="
{"answer_permalink": "http://127.0.0.1:8000/questions/1", "answer_id": 16, "question_text": "What were the skies like when you were young?", "answer_text": "test", "question_id": "1"}

I am making the request from an HTML file on my local machine that is not being served by a web browser. It's just addressed using file://. The django server is also local, at 127.0.0.1:8000, the default location.

Thanks for any suggestions!

-Jim

+1  A: 

Unless you specifically allow your browser alternate settings for local files, everything remains bound by the cross-domain security policy. Files not on a domain (like localhost) can not request files from that domain.

I'm not sure how cross-domain policy works with ports; you may be able to put this file in your port-80-accessible localhost folder (if you have one) and get the job done. Otherwise, you're stuck, unless you can change browser settings to make exceptions (and even then I'm not sure this is doable in any standard browsers).

Matchu
OK, so when I put the script in my static media directory inside the Django runserver, the response works! The thing is, POSTing always worked. Only the response is blank, cross-domain, and only for some clients (remember `curl` worked).If this is part of the cross-domain security model, I don't really get it. Allowing me to send data, but not receive a response, across domains doesn't seem like the best way to prevent people getting in to trouble.Then again, I am new to front-end coding, so please feel free to prove me wrong.
Jim N
You're right - that doesn't really make sense. (I'll point out that `curl` is immune to cross-domain policies, since it's not on any domain.) Of course, the real danger in cross-site communication via AJAX is data access; automatically *sending* requests via CSRF is easily achievable through other means (e.g. image tags, iframe with an auto-submitting form), so protecting against similar attacks should be implemented on a different level, anyway.
Matchu
+1  A: 

Add an "error: function(data){alert(data);}" to see if your $.ajax is failing.

Robert
+1  A: 

Change 'complete' to 'success' in your .ajax() call. 'complete' is used to signal when the ajax operation is done but does not provide the response data. 'success' is called with a successful request and receives the response. 'error' is the counterpart to 'success', used for error handling.

I think browsers (at least some, like Safari, for me) treat files served off the file system as trusted sources in terms of the same-origin policy. So that turned out to be a red herring here.

Brad Choate