I've got an http 501 error bubbling up in prod from this call:
return $.ajax({
url: finalUrl,
success: function (result) {
console.log('success call result');
console.log(result);
finalResult = result;
},
data: JSON.stringify(data),
type: 'PATCH',
contentType: 'application/json'
});
How can I return a mock simulating the error so I can test a fix outside of production? I looked at the response tab in chrome and I see an HTML message:
<HTML><HEAD>
<TITLE>Unsupported Request</TITLE>
</HEAD><BODY>
<H1>Unsupported Request</H1>
PATCH to http://demo.site.com/serviceName/v1/requests/9305e338-666a-e611-8516-000c291891bb not supported.<P>
Reference #8.f0fd717.1472154919.9959c96
</BODY></HTML>
We suspect that the API is not being hit at all, blocked by a firewall. I don't know if I should expect a string or object in this case? If object, then what are the members of that object?
Fiddler says:
Server: AkamaiGHost
Mime-Version: 1.0
Content-Type: text/html
Content-Length: 350
Expires: Thu, 25 Aug 2016 20:21:49 GMT
Date: Thu, 25 Aug 2016 20:21:49 GMT
Connection: close
We suspect that the API is not being hit at all, blocked by a firewall.
From the error, it looks like you're hitting a back-end that isn't configured for that request-type.
See these questions for a potential solution, assuming you control the back-end too.
Does tomcat support http PATCH method?
How do I stop Apache httpd from rejecting HTTP PATCH requests?
If you do control the back-end, but the above doesn't help, make sure that your controller function supports that request method. In Spring, for example, you have to declare that explicitly:
#Controller
MyController {
#Requestmapping(value = "/api/patchTheThing", method=RequestMethod.PATCH)
#ResponseBody String patchTheThing(....) {
...
}
}
Just set up an endpoint on a server of your choice and use your web server configure or coding language of your choice to issue a 501 response. But the problem seems pretty clear, the server is not expecting a PATCH request. If you had some networking problem you would not be getting a response at all.
you should strongly consider making sure your JavaScript code handles both happy path / success outcome as well as other types off sever response outcomes so your application can better handle how it wants to recover from such errors.
Related
Trying to make a call and retrieve a very simple, one line, JSON file.
$(document).ready(function() {
jQuery.ajax({
type: 'GET',
url: 'http://wncrunners.com/admin/colors.json' ,
dataType: 'jsonp',
success: function(data) {
alert('success');
}
});
});//end document.ready
Here's the RAW Request:
GET http://wncrunners.com/admin/colors.json?callback=jQuery16406345664265099913_1319854793396&_=1319854793399 HTTP/1.1
Host: wncrunners.com
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.106 Safari/535.2
Accept: */*
Referer: http://localhost:8888/jquery/Test.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Here's the RAW Response:
HTTP/1.1 200 OK
Date: Sat, 29 Oct 2011 02:21:24 GMT
Server: Apache/1.3.33 (Unix) mod_ssl/2.8.22 OpenSSL/0.9.7d SE/0.5.3
Last-Modified: Fri, 28 Oct 2011 17:48:47 GMT
ETag: "166a2402-10-4eaaeaff"
Accept-Ranges: bytes
Content-Length: 16
Content-Type: text/plain
Connection: close
{"red" : "#f00"}
The JSON is coming back in the response (red : #f00), but Chrome reports Uncaught SyntaxError: Unexpected token : colors.json:1
If I navigate directly to url itself, the JSON is returned and is displayed in the browser.
If I paste the contents of colors.json into JSLINT, the json validates.
Any ideas why I can't get this error and I never make it to the success callback?
EDIT - the jQuery.ajax() call above runs perfect at jsfiddle.net, and returns the alert 'success' as expected.
EDIT 2 - this URL works fine 'http://api.wunderground.com/api/8ac447ee36aa2505/geolookup/conditions/q/IA/Cedar_Rapids.json' I noticed that it returned as TYPE: text/javascript and Chrome did not throw the Unexpected Token. I've tested several other url's and the ONLY one that does not throw the Unexptected Token is the wunderground that is returned as TYPE: text/javascript.
Streams returned as text/plain and application/json are not being parsed correctly.
You've told jQuery to expect a JSONP response, which is why jQuery has added the callback=jQuery16406345664265099913_1319854793396&_=1319854793399 part to the URL (you can see this in your dump of the request).
What you're returning is JSON, not JSONP. Your response looks like
{"red" : "#f00"}
and jQuery is expecting something like this:
jQuery16406345664265099913_1319854793396({"red" : "#f00"})
If you actually need to use JSONP to get around the same origin policy, then the server serving colors.json needs to be able to actually return a JSONP response.
If the same origin policy isn't an issue for your application, then you just need to fix the dataType in your jQuery.ajax call to be json instead of jsonp.
I have spent the last few days trying to figure this out myself. Using the old json dataType gives you cross origin problems, while setting the dataType to jsonp makes the data "unreadable" as explained above. So there are apparently two ways out, the first hasn't worked for me but seems like a potential solution and that I might be doing something wrong. This is explained here [ https://learn.jquery.com/ajax/working-with-jsonp/ ].
The one that worked for me is as follows:
1- download the ajax cross origin plug in [ http://www.ajax-cross-origin.com/ ].
2- add a script link to it just below the normal jQuery link.
3- add the line "crossOrigin: true," to your ajax function.
Good to go! here is my working code for this:
$.ajax({
crossOrigin: true,
url : "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.86,151.195&radius=5000&type=ATM&keyword=ATM&key=MyKey",
type : "GET",
success:function(data){
console.log(data);
}
})
I had the same problem and the solution was to encapsulate the json inside this function
jsonp(
.... your json ...
)
That hex might need to be wrapped in quotes and made into a string. Javascript might not like the # character
I have been trying to get hold of the cookies I am setting in the server using PlayFramework:
response().setHeader(SET_COOKIE, AppConstants.COOKIE_USER_SESSIONID+"="+appSession.getSid());
in the angular app, but am not able to.
If I use the Advanced Rest client, I get the SetCookie header and the cookies get set in the call that follows. However when I call the same api through my angular app, I am not able to get the header in the response and hence no cookies for the app.
Here's what I have already tried:
renaming the environment from localhost to xyz.com since I read on multiple answers that cookies do not work at localhost.
Tried the api form a separate rest client, was able to fetch the header successfully, so the API looks fine to me.
There should be some catch in angular code which I am not able to figure out. Any help on this is highly appreciated. Thanks.
Angular code snippets:
LoginController:
angular.module('wratApp')
.controller('LoginCtrl', function (postService, wratSettings, wratRoutes, $location, $cookies) {
$("#header").hide();
this.user= {};
this.logUserin = function(){
console.log("User: " + this.user.email + " & pwd: " + this.user.pwd);
var payLoad = {};
payLoad.ldap = this.user.email;
payLoad.pwd = this.user.pwd;
postService.postPromise(wratRoutes(wratSettings).POST_USER_LOGIN(),payLoad)
.then(function(){ //login success
console.log("login success");
$location.path(wratRoutes().CLIENT_HOME());
}, function(){ //error in login
console.log("Login failed");
})
;
}
});
postService:
angular.module('wratApp')
.factory('postService', function ($http, $q, $cookies, $location) {
function postService() {
var self = this;
self.postPromise = function (uri,payload){
var deferred = $q.defer();
$http.post(uri,payload)
.success(function(data, status, headers, config){
console.log("Got response cookies: "+$cookies.getAll());
deferred.resolve(data);
})
.error(function(data, status, headers, config){
if(status == 401){
angular.forEach($cookies.getAll(), function (v, k) {
$cookies.remove(k);
});
$location.path('/login');
}else{
deferred.reject(data);
}
});
return deferred.promise;
}
}
return new postService();
});
Now, my login succeeds but without any cookies being set by the server. Also, the PlaySession cookie which is somehow visible in the debugger(the manually set ones are even absent from debugger), is not in the angular $cookies variable(refer image below).
Please suggest how can I resolve this. Thanks.
Update 1:
If I run the Play server not in debug mode, the cookies are appropriately being sent by the server. It's an issue with the angular app where in the following call, it's not transferring the values form the Set-Cookie header to the cookies for the next call. It might be some silly mistake on my end too. Please see if you can help me figure out.
Server response /login:
HTTP/1.1 200 OK
Vary: Origin
Set-Cookie: sid=1e6823e24554598b0521ca5f64d7746b; Path=/
Set-Cookie: PLAY_SESSION=953d9d5730bf1b77cccaadef6b78c209e59d924b-sid=1e6823e24554598b0521ca5f64d7746b; Path=/; HTTPOnly
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: http://wrat.com:9009
Access-Control-Allow-Methods: OPTIONS, GET, POST
Access-Control-Allow-Credentials: true
Date: Thu, 24 Sep 2015 22:27:03 GMT
Content-Length: 429
The following request which should have cookies set, but no cookies there :-( :
GET /products/all HTTP/1.1
Host: wrat.com:9000
Accept: application/json, text/plain, */*
Origin: http://wrat.com:9009
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36
Referer: http://wrat.com:9009/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Taking off the Play framework tag since it's not a play issue anymore.
Adding the withCredentials option to the $http calls worked for me and resolved the issue.
$http.post(uri,payload, {withCredentials: true})
The issue is with the ajax calls where if this withCredentials flag is not truthy at both server and client, the cookies set by server are not maintained for cross-origin calls. Hence it was totally ignoring the cookies I was setting from the server.
Text from following question helped resolve the problem:
Why is jquery's .ajax() method not sending my session cookie?
from:
I am operating in cross-domain scenario. During login remote server is
returning Set-Cookie header along with
Allow-Access-Control-Credentials set to true.
The next ajax call to remote server should use this cookie.
CORS's Access-Control-Allow-Credentials is there to allow cross-domain
logging. Check https://developer.mozilla.org/En/HTTP_access_control
for examples.
For me it seems like a bug in JQuery (or at least feature-to-be in
next version).
UPDATE:
Cookies are not set automatically from AJAX response (citation:
http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/)
Why?
You cannot get value of the cookie from response to set it manually
(http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader)
I'm confused..
There should exist a way to ask jquery.ajax() to set
XMLHttpRequest.withCredentials = "true" parameter.
ANSWER: You should use xhrFields param of
http://api.jquery.com/jQuery.ajax/
The example in the documentation is:
$.ajax({ url: a_cross_domain_url, xhrFields: {
withCredentials: true } }); It's important as well that server answers correctly to this request. Copying here great comments
from #Frédéric and #Pebbl:
Important note: when responding to a credentialed request, server must
specify a domain, and cannot use wild carding. The above example would
fail if the header was wildcarded as: Access-Control-Allow-Origin: *
So when the request is:
Origin: http://foo.example Cookie: pageAccess=2 Server should respond
with:
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true
[payload] Otherwise payload won't be returned to script. See:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials
I'm trying to get some JSON data from a REST API, but when I call it cia an AJAX request with dataType param as jsonp it gives me an error that the jQuery 'callback was not called'. This is the error message:
Error: Status: parsererror Message: Error: jQuery2130732580496231094_1429605569499 was not called
So, if I try to make this request without jsonp, using JSON as the dataType, it gives me another error about the CORS:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
I know this is an idiot question, but I've read about CORS and just don't get where to put it's params to enable it. For me, the right is to use the first method that I've used, but after looking for an answer for that problem, I just don't understand anything. If someday I could understand where to put the CORS I should be use to make the request as another way.
So they are my questions, here is my code:
$.ajax({
url: 'eztvapi.re/shows/1';,
type: 'GET',
dataType: 'jsonp',
crossDomain: true,
success: function(data) {
//data = JSON.parse(data);
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("Error: Status: " + textStatus + " Message: " + errorThrown);
}
});
This are my headers request from the console:
Remote Address:216.58.222.12:443
Request URL:http://eztvapi.re/shows/1?callback=jQuery213010618196451105177_1429606458524&_=1429606458525
Request Method:GET
Status Code:200 OK
Response Headers
cache-control:private
content-encoding:gzip
content-type:application/json; charset=utf-8
date:Tue, 21 Apr 2015 08:54:22 GMT
etag:W/"0hnqCn40L98JLmwY2UfUlg=="
server:nginx
status:200
vary:Accept-Encoding
via:1.1 Chrome-Compression-Proxy
x-powered-by:Express
x-response-time:32ms
x-served-by:us-la3
Request Headers
:authority:eztvapi.re
:method:GET
:path:/shows/1?callback=jQuery213010618196451105177_1429606458524&_=1429606458525
:scheme:http
accept:*/*
accept-encoding:gzip, deflate, sdch
accept-language:pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4
chrome-proxy:ps=1429584828-1395746459-275388119-220935266, sid=a259cd2eeb457c7a40ff6367868ef723, c=win, b=2311, p=90
user-agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36
Query String Parameters
view source
view URL encoded
callback:jQuery213010618196451105177_1429606458524
_:1429606458525
And this are the json object that the request returns, BUT IT ONLY APPEARS ON THE CONSOLE NETWORK PART:
0: {_id: "tt0944947",…}
1: {_id: "tt0903747",…}
2: {_id: "tt0898266",…}
3: {_id: "tt1520211",…}
4: {_id: "tt0773262",…}
5: {_id: "tt0460649",…}
6: {_id: "tt1475582",…}
7: {_id: "tt2193021",…}
8: {_id: "tt1796960",…}
9: {_id: "tt1119644",…}
10: {_id: "tt0411008",…}
I've done recently a lot of requests for another rests,so i think the client's side is correctly. This is a new server that i'm testing my requests, but this is not my server domain, this belows to a popular rest server and i believe that supports json call. What is funny and i've asking myself since i've start with this new one is the response that i'm getting. You can see that server answers my request with the correctly data, but i can't get the data to my javascript, to print it or process it.
Thank you for any help.
Error: Status: parsererror Message: Error: jQuery2130732580496231094_1429605569499 was not called
The server you are requesting data from has to support JSONP in order for you to make a successful JSONP request to it.
See the Wikipedia article on the subject for details of how to do that.
I've read about CORS and just don't get where to put it's params to enable it.
In the HTTP response headers of the service you are making the request to.
e.g. Your page on example.com wants to use JS to get data from example.net. Therefore example.net has to tell the user's browser that example.com is allowed access to the data.
To enable CORS requests, you have to allow this type of request from your server part and create a request from your client which will be allow to get cors resources :
Only use GET, HEAD or POST and content type application/x-www-form-urlencoded, multipart/form-data, or text/plain.
Your client part seems to be correct, I think you have to deal with the server to allow this type of request.
you can have more informations here
Finally, after a couple of days studying this problem i've solved this. Not from the most easy way, but... solved :D
I wrote an app with express and request on NodeJs, and using the request it returned me all the json object. Now i could just send it to my javascript var with the express.
Thanks for all the replies guys! Peace.
We are developing a mobile site using html5, jQuery(1.8.2) and jQuery mobile while making jQuery ajax calls (get and post).
After we changed our domain name, we are getting "access denied" for ajax calls on ie9.
We tried to include jquery.iecors.js. But still we are getting the same error.Is there any resolution for this?
Sample Code:
$.support.cors = true;
$.ajax({
cache: false,
async: true,
crossDomain: true,
timeout: 600000,
url: baseUrl + '/SmartTouch/restServices/PrefferedHotels',
type: 'GET',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + myencoded);
},
contentType: "application/x-www.form-urlencoded; (http://www.form-urlencoded;) (http://www.form-urlencoded;) charset=UTF-8",
success: function (data) {
alert("success");
},
error: function (jqXHR, textStatus, errorThrown) {
alert("error!!::" + JSON.stringify(jqXHR));
alert('response: ' + jqXHR.responseText);
alert('code: ' + jqXHR.getResponseHeader('X-Subscriber-Status'));
alert("textStatus " + textStatus);
alert("errorThrown " + errorThrown);
}
});
Edited:
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + myencoded);
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.setRequestHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
},
contentType: "application/x-www.form-urlencoded; (http://www.form-urlencoded;) (http://www.form-urlencoded;) charset=UTF-8",
success: function (data) {
alert("success");
},
error: function (jqXHR, textStatus, errorThrown) {
alert("error!!::" + JSON.stringify(jqXHR));
Request and Response headers in IE9:
Request:
Key Value
Request GET url HTTP/1.1
Accept text/html, application/xhtml+xml, */*
Accept-Language en-US
User-Agent Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding gzip, deflate
Proxy-Connection Keep-Alive
Host ("url")
Pragma no-cache
Cookie GUEST_LANGUAGE_ID=en_US; COOKIE_SUPPORT=true; __utmc=24444716; __utma=24444716.47018335.1379597653.1380274476.1380276859.17; __utmz=24444716.1379597653.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=24444716.6.10.1380276859
Response:
Key Value
Response HTTP/1.1 200 OK
Server Apache-Coyote/1.1
X-Powered-By Servlet 2.5; JBoss-5.0/JBossWeb-2.1
Accept-Ranges bytes
ETag W/"64578-1380266616000"
Last-Modified Fri, 27 Sep 2013 07:23:36 GMT
Content-Type text/html
Date Fri, 27 Sep 2013 10:17:01 GMT
Content-Length 64578
Age 0
Via 1.1 localhost.localdomain
This kind of Content-Type looks strange:
application/x-www.form-urlencoded; (http://www.form-urlencoded;) (http://www.form-urlencoded;) charset=UTF-8"
I can imagine the IE has as problem with it.
Try the proper one:
application/x-www-form-urlencoded; charset=UTF-8
^-- notice: no dot!
It's also possible for the IE to have problems with the authorization.
Maybe myencoded is out of the scope or not filled correctly. Debug this variable and have a look at this question: Authorization through setRequestHeader
If you want the Ajax url to be hit from any domain, the server must send a response header Access-Control-Allow-Origin : * or Access-Control-Allow-Origin : your-domain if restricted only to your domain.Can you see these headers in response?
See this Microsoft article on CORS implementation on IE8 and IE9: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
Specifically they say two things:
No custom headers may be added to the request
and
No authentication or cookies will be sent with the request
And you mentioned in your comment:
Our problem is we are doing basic authorization and including following header: xhr.setRequestHeader("Authorization", "Basic " + myencoded); in our ajax call.But in ie9 we are getting access denied.Is there any way to include this header?
Unfortunately, the answer I'll have to give you is no, there is no way to include this header in IE8 or IE9. Microsoft designed it that way.
To get it to work with CORS on IE9 you'll have to convince the site you're connecting to to allow you to send authorization information some other way - maybe query params or post data.
If the site is not cooperative there's always the request proxy work-around where you request to a page on your server and you server forwards the request with the correct header etc.
You seem confident that the issue has nothing to do with the suggested jQuery bug (especially since you're using jquery.iecors.js) so I'll move right on.
What is the significance of the "edited" bit? Access-Control-Allow-Origin:* should be set on the response (i.e. server-side, as part of Apache/IIS/F5 configuration), not on the request. Edit: there is more information available on MDN; you could also use something like burp's tampering proxy to play with the headers if you don't have immediate access to config changes (pretty common in an enterprise environment)
Even if not an issue, #DanFromGermany is absolutely right - content-type does look strange. You shouldn't even have to set it manually, jQuery.ajax() has it correct by default.
You also seem concerned with setting the basic authentication header. Remember that myencoded value is just encoded (not encrypted), so you might as well skip the header and pass credentials in the URL: http(s)://username:password#www.example.com/
Moar edit:
Looking through those MDN docos above, this seems relevant:
By default, in cross-site XMLHttpRequest invocations, browsers will
not send credentials. A specific flag has to be set on the
XMLHttpRequest object when it is invoked.
Perhaps try adding xhr.withCredentials = true; to your beforeSend?
Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example
would fail if the header was wildcarded as:
Access-Control-Allow-Origin: *. Since the Access-Control-Allow-Origin
explicitly mentions http://foo.example, the credential-cognizant
content is returned to the invoking web content.
This would invalidate previous advice of using an asterisk in the header (i.e. explicit domain is required)
If you were using windows based hosting?
Please check old configs for the IIS, if available,
there are security provisions which will allow content by its type,
add this response header <% Response.AddHeader("Access-Control-Allow-Origin","*") %> in your page also.
or refer the source link to MSDN for more details
I think you have updated this in edits but there are many things as its AJAX involved, and your IE9 may also one of the reason if you have changed security options and not default.
I think that should do, if not please reply
You can try this
<meta http-equiv="X-UA-Compatible" content="IE=Edge" >
It forces the browser the render at whatever the most recent version's standards are. For reference http://msdn.microsoft.com/en-us/library/ie/ms533876%28v=vs.85%29.aspx
I'm building a web app with Django. I have a bunch of API calls in Javascript via Ajax (jQuery v1.8.3).
Most of them work, but a particular one results in a return object with status 0 and this message as the statusText:
[Exception... "'JavaScript component does not have a method named: "available"' when calling method: [nsIInputStream::available]" nsresult: "0x80570030 (NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED)" location: "JS frame :: http://127.0.0.1:8000/media/js/jquery.js :: .send :: line 8434" data: no]
The corresponding line in jQuery is xhr.send( ( s.hasContent && s.data ) || null );
However, this occurs only in Firefox. Chrome works fine. Again, other requests do work. The only thing which sets this one apart is the DELETE http method.
The request is as follow (HTTP network data shown in Chrome – Firebug doesn't show anything in Firefox):
Request URL: http://127.0.0.1:8000/api/reservation/13/
Request Method: DELETE
Status Code: 400 BAD REQUEST (This is expected)
Request Headers
Accept: application/json, text/javascript, */*; q=0.01
Content-Length: 15
Content-Type: application/json
Origin: http://127.0.0.1:8000
Referer: http://127.0.0.1:8000/reservation/
X-Requested-With: XMLHttpRequest
Request Payload
[object Object]
Response Headers
Cache-Control: no-cache
Content-Type: text/html; charset=utf-8
Date: Tue, 02 Apr 2013 19:18:35 GMT
Server: WSGIServer/0.1 Python/2.7.2
On the server, I don't receive any request.
The JS code is (taken directly from Firebug Watch at breakpoint):
options = {
contentType: "application/json",
data: Object {},
dataType: "json",
processData: false,
type: "DELETE",
url: "/api/reservation/13/",
error: function(),
success: function()
};
$.ajax(options);
I also did try to disable all extensions in FF. I run v20.0.
The problem was a combination of Firefox with jQuery/XMLHttpRequest and sending an object via HTTP DELETE. Once JSON'ifying the object via JSON.stringify() everything worked.
Still, a strange exception for Firefox to throw.
Thanks to freddyb for that idea.
The problem was with the property called processData within the $.ajax function. When this property is supplied as "false" (don't know why) Firefox doesn't like it, and as consequence, the browser doesn't digest the JSON request/response package. Chrome and Safari works just fine.
This happens (as of 2014 with FireFox 32) with any non-GET AJAX request when the request data object is an empty object, like {}. I am using Mithril.js and it may be related to the fact that Mithril always sets a Content-Type for non-GET requests. This was absolutely repeatable once I knew the trigger.
(Note that the "non-GET" part may not be entirely accurate -- Mithril ignores the data object if it's a GET so sending an empty object with GET using the underlying AJAX object may also fail in the same way.)
Counter-intuitively, setting data to an empty string, "", does not fail in this way, so that was my work-around. I actually don't set data at all when there is none, and if it's unset by the time I send the request (in my AJAX wrapper) I default it to "".
It sounds like you have a buggy Firefox extension installed which is trying to examine the XMLHttpRequest data and failing....
I suggest you try http://support.mozilla.org/en-US/kb/troubleshoot-firefox-issues-using-safe-mode or just disabling whatever Firefox extensions are involved.