jQuery Ajax Requests: Handling JSON Response in Ubiquitous Manner - javascript

I have a PHP script which sends me back JSON (with proper headers, confirmed by response headers in Chrome Dev Tools). When I do a POST request in jQuery, like this:
var request = $.post(formAction, formData);
I "need" to handle accessing JSON properties differently for .done() and .fail() (details being a property), thus:
request.done(function(response) {
$('#response').text(response.details);
});
request.fail(function(response) {
$('#response').text(response.responseJSON.details);
});
What is the recommended way of accessing JSON properties in ubiquitous manner, so I can just call a always() function ? For instance, when the fail() method fires, and I do console.log(response.details) I get errors telling me that that property is not found.

Related

getjson - not returning object to console

I am trying to retrieve a json feed every 1 second. The URL that I am trying to retrieve displays JSON in the browser but will not be retrieved via a jquery getJSON
http://www.ridestreamline.com/Services/JSONPRelay.svc/GetMapVehiclePoints
function getBusLoc() {
$.getJSON('http://www.ridestreamline.com/Services/JSONPRelay.svc/GetMapVehiclePoints?callback=?', function(data) {
console.log(data);
setTimeout(getBusLoc, 1000);
})
}
getBusLoc()
It has something to do with the above link. What am I missing? Fiddle here
This is because of same origin policy, you can't sent ajax request from host A to host B, you can use jsonp instead (if your service supports this) , or if you has control to server side and you don't mind to old browsers you can use x-access-control-allow-origin http header in response to OPTIONS request (more info here https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS)

"Security Err: Dom Exception" thrown when nesting ajax calls

Here's the issue. I'm extracting gmail contacts through an ajax call in javascript/jquery like this:
function getUserInfo() {
var xml_parse = "";
$.ajax({
url: SCOPE + '?max-results=9999&access_token=' + acToken
data: null,
success: function (resp) {
xml_parse = $.parseXML(resp);
callGmailHelperWebService(xml_parse);
},
dataType: "jsonp"
});
}
function callGmailHelperWebService(xml_parse) {
GmailHelperService.ConvertXMLToList(xml_parse, onSuccess, onFailed, null);
}
So, as you can see, if the initial ajax call is successful, i call a function which calls a web service that sits on the save server as my project (in fact, it's part of the project).
My web service (GmailHelperService) is wired up correctly, as I can definitely call it in other places (like right after this ajax call, for example). However, when I try to call it within the "success" portion of the ajax call, i get the following error:
Uncaught Error: SECURITY_ERR: DOM Exception 18
My theory is that this has something to do with cross-domain issues, but I can't understand why. And I certainly can't figure out how to fix this.
I'd appreciate any help.
JSONP is a data transfer method that involves sending your data in this format:
callback({"foo":"bar"});
As you can see, this is NOT xml. It is JSON wrapped in a callback method that will get executed when the request is done loading, thus allowing it to be cross-domain because it can be requested using a <script> tag.
You cannot simply change your dataType to JSONP and return xml, expecting it to work. XML != JSONP. You can however return XML in jsonp, for example, callback({"xml","... xml string here "}) but be mindful of quotes, all json keys and values must be wrapped in double quotes, inner-quotes need to be handled appropriately.
If your request is a same domain request (Same protocol, same subdomain, same domain, and same port,) then you can change your dataType to "XML" if you are returning XML. Otherwise, you need to either setup a proxy script to get the xml for you, or have your webservice return JSONP.
For example, the following urls are all considered cross-domain from each other.
http://example.com
http://www.example.com
https://example.com
https://www.example.com
http://example.com:8080
All of the above urls would be considered cross-domain, even if they are on the same server.

Modify jQuery Request Headers before send

I have a single page js app and I'm sending custom headers to my server containing logs, but i need to control the size of those headers because my server won't accept requests larger then 8k.
My solution thus far was to intercept all outgoing ajax request from my application.
I'm using jQuery Global Ajax Events, particularly ajaxSend to intercept all requests. I cannot use beforeSend because that is a local event.
I can't seem to access the request headers in the callback. I need to read all request's header and cut down the logs header if it's too large.
You want to use beforeSend to modify the request before it is being sent. This is all covered in the documentation you've linked to.
The global ajaxSend event will not help you tamper with the request. The closest thing to global you can get would be to is call ajaxSetup, passing a beforeSend option to be default for all subsequent ajax calls.
There appears to be no simple way of getting request headers from an XMLHttpRequest object. Since I assume you're setting your logging headers yourself, however, you might be able to hook into the setting of these headers, and store an accessible reference to them:
XMLHttpRequest.prototype.readableHeaders = {};
XMLHttpRequest.prototype.proxiedSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.setRequestHeader = function(header, value) {
this.proxiedSetRequestHeader(header, value);
this.readableHeaders[header] = value;
};
In this manner, you should be able to directly inspect the jqXHR.readableHeaders object for your specific logging header, in beforeSend, and call setRequestHeader once more, to truncate the string, if needed.
To retrieve the headers you need access to the underlying instance of XMLHttpRequest from jqXHR object. Use xhr() function to retrieve the instance.
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
console.log( settings.xhr().readableHeaders );
}
});

Why does this $.getJSON request error?

I have the following script that call a http handler. It calls the http handler, and in fiddler, I can see the JSON returned correctly, however this script always ends up in the error block. How can I determine what is wrong?
<script type="text/javascript">
function GetConfig() {
$.getJSON("http://localhost:27249/Handlers/GetServiceMenuConfiguration.ashx", function(d) {
alert("success");
}).success(function(d) {
alert("success");
}).error(function(d) {
alert("error");
}).complete(function(d) {
alert("complete");
});
}
</script>
I see that you're including the server name (localhost) and port (27249). Ajax requests are controlled by the Same Origin Policy, which forbids cross-origin requests in the normal case. (If you're not doing a cross-origin call, you don't need to include the http://localhost:27249 portion of your URL, which is what makes me think you might be doing one.)
You can do cross-origin calls if the browser supports them and if your server code handles the CORS requests properly. Alternately, you might look at using JSON-P.
JQuery's built-in JSON parser is rather picky, even well formatted JSON can sometimes fail if the headers are not set perfectly. First try to do a $.ajax request with type:text property and log the response. This will differentiate between a connection problem and parse problem.
$.ajax({
dataType:'text',
url: '/Handlers/GetServiceMenuConfiguration.ashx',
success: function(data) {
console.log(data.responseText);
}
});
If the problem is the connection, and you do need to request JSON across domains, then you could also use a library loader like LAB, yep/nope or Frame.js.

How do I access the JSON response with jQuery.Ajax for a 400 error?

In jQuery, I'm submitting forms to the server. When there is a validation error, I receive a 400 error from the server, and the body of the document is valid JSON. I would like to know how to access the data returned from the server.
My .error callback function on the jQuery.Ajax object is never called, so I'm using .statusCode{400} function. This runs just fine, however none of the arguments contain the response body.
I try to get json response with a status 400, and it works on IE7,8 and 9, Firefox and Chrome (Safari not tested).
...
error: function(xhr) {
error(xhr.responseText);
}
...
Some browsers' XHR implementations refuse to provide the response body if the HTTP status is not 2xx. What I've had to resort to in API design where I couldn't control my clients was to do something like always return 200 and indicate success/failure/status in some other way (e.g., as a top-level attribute in the JSON response).
I have had no trouble using statusCode in the callback, However, statusCode as a callback function Does NOT return any data.
jQuery.Ajax
I think you should try a different approach on how to handle validation errors in the server side, to return status code 200, but with a parameter like "error_count" and go from there.
can you post some of the code you are using (just $.ajax you are using...) ?
For me (Chrome), responseText property of the xhr response contains only "BAD REQUEST" when statusCode is 400. Thanks Steven for your response; I was struggling with this since in Postman I could get the json data I was returning from my REST controller, but couldn't find it on the jQuery Ajax response.
"If json is specified, the response is parsed using jQuery.parseJSON before being passed, as an object, to the success handler. The parsed JSON object is made available through the responseJSON property of the jqXHR object."
http://api.jquery.com/jquery.ajax/
If you're specifying your callback with statusCode as mentioned in the question:
"If the request is successful, the status code functions take the same parameters as the success callback; if it results in an error (including 3xx redirect), they take the same parameters as the error callback." (jqXHR, textStatus, errorThrown)

Categories

Resources