Ajax request to current path requests `text/html` instead of `application/json` - javascript

I have two almost identical JQuery requests that I issue after the page loads, the first one requests json for the current path and the second for a different url. I was surprised to see, though, that the first request type is text/html and the second is application/json. I would have expected both to be application/json. The requests look something like this:
$.ajax({
url: window.location.pathname,
type: 'GET',
dataType: 'json',
success: doSomething
});
$.ajax({
url: '/tags',
type: 'GET',
dataType: 'json',
success: doSomethingElse
});
Yet in the network tab I'm seeing:
What am I missing?

dataType: 'json' has two main effects:
It causes jQuery to ignore the content-type of the document it gets back from the server and to treat it as JSON regardless
It sets an Accept header (for HTTP content negotiation) requesting JSON
The server may use HTTP content negotiation to decide what to put in the response if it has different representations of the content in different formats. Most servers do not.
It looks like yours does not. It will always return HTML for the first URL and always return JSON for the second URL.
If you want your server to pay attention to the Accept header, then you have to configure it to do so (as well as providing a JSON version of the document as well as the HTML version).

The content type shown is the type of the response the server is sending you, not the type of request you are sending to the server.

Related

Content-Type Ajax json missing

I wrote some php code that outputs some valid json, and sets the content-type header to application/json in my dev setup. However when I deploy this script to a embedded webserver it works fine except it's not capable of sending the content-type. It's not possible to run a other webserver.
Now I have the following code for Dynatable. Even though my dev and my embedded webserver, serve exactly the same file, and the only difference is the content-type. It works for my dev setup, however it doesn't work for my embedded setup.
I use the following code to load the json file to dynatable.
document.ready(
$.ajax({
url: 'phpApi.php',
success: function(data){
$('#myTable').dynatable({
dataset: {
records: data
}
});
}
}));
So can someone explain me why the content-type is so important for ajax? How can I tell my code manually its json?
Without the content-type the returned data is assumed to be plain text. There is nothing in your code to tell it otherwise.
One way to get json would be to specify the return type in the jquery code. Just add dataType: 'json' into the ajax configuration.
Or you could use eval() to transform the returned text to json.
document.ready(
$.ajax({
url: 'phpApi.php',
success: function(data){
$('#myTable').dynatable({
dataset: {
records: eval(data)
}
});
}
}));
Using JSON.stringify(eval(data)) might give you better results by making sure its json.
As pointed out below, JSON.parse(data) would probably be safer. (Eval is evil after all.)
So can someone explain me why the content-type is so important for ajax?
It's important so the client can identify what type of content the server returned, content-type: application/json tells jQUery to parse the data as an object. If no content type is returned, the client will assume the returned data is just plain text.
How can I tell my code manually its json?
Add dataType: "json" parameter to $.ajax()
document.ready(
$.ajax({
url: 'phpApi.php',
dataType: "json",
success: function(data){
$('#myTable').dynatable({
dataset: {
records: data
}
});
}
}));

Ajax response with JSONP, can see result cannot use it

I have the following javascript:
jQuery(document).ready( function($) {
var id = "123";
var api = "example.com:8999/".concat(id)
$.ajax({
url : api,
type: 'GET',
dataType: 'jsonp',
// jsonpCallback: "localcallback",
success: function (data) { alert('success'); }
})
});
I can see the response in chrome dev tools, but the alert isn't getting called. Ultimately I need to work with this response to set the value of a div.
Image of chrome tools:
Thanks
EDIT: Put 'POST', was using 'GET', still not working. Also, I think I'd prefer "mom and pop" json, but due to CORS and the fact I'm not good with the web and am just trying to hack this together.
Your server is not returning JSONP. It's returning plain JSON. If you specify JSONP, then the server must explicitly create a JSONP formatted response or the ajax response will not be received and processed properly.
FYI, a JSONP request is sent via a script tag (that's how it gets around the same-origin limitation for cross domain requests) and the response has to be formatted as a script that calls a function and passed the requested data to that function. You can read about how JSONP works here.
Just make your ajax call without specifying the 'dataType' attribute, then control should come back to your success callback if your ajax call completes successfully.
FYI: jQuery will try to find the response data type based on the MIME type of that response.
Example:
$( function() {
$.ajax({
url :"http://example.com:8999/123",
type: 'GET',
success: function (data) {
console.log(data); // Prints the response on console
alert('success');
}
})
});
If you want to make this call only with JSONP then it would be better to share the reason with us, so that we can suggest a better solution if possible.

jQuery $.ajax done callback not firing

I have the following code :
$("#loginSubmitButton").on("click",function(){
var loginUserDetails = {
email: $("#email").val(),
password: $("#password").val()
};
//Send the AJAX request to authenticate the user
$.ajax({
type: "POST",
url: "/somewebservice/v1/users/authenticate",
data: JSON.stringify(loginUserDetails),
contentType: "application/json;charset=UTF-8",
dataType: "json",
}).done(function() {
$("#loginResult").text("Login successful");
})
.fail(function() {
$("#loginResult").text("Login failed");
});
});
As per the jquery documentation (unless I am understanding something incorrectly) I expect the done to be fired if I receive a 200 OK from my web server. However, in chrome console I can see a 200 OK response but jquery seems to fire the fail handler.
Does anyone have any idea what I might be doing wrong here?
You need to remove:
dataType: "json"
There are lots of suggestions to remove
dataType: "json"
While I grant that this works it's probably ignoring the underlying issue. It's most likely caused by a parser error (the browser parsing the json response). Firstly examine the XHR parameter in either .always() or .fail().
Assuming it is a parser fail then why? Perhaps the return string isn't JSON. Or it could be errant whitespace at the start of the response. Consider having a look at it in fiddler. Mine looked like this:
Connection: Keep-Alive
Content-Type: application/json; charset=utf-8
{"type":"scan","data":{"image":".\/output\/ou...
In my case this was a problem with PHP spewing out unwanted characters (in this case UTF file BOMs). Once I removed these it fixed the problem while also keeping
dataType: json
If your server returns empty string for a json response (even if with a 200 OK), jQuery treats it as failed. Since v1.9, an empty string is considered invalid json.
Whatever is the cause, a good place to look at is the 'data' parameter passed to the callbacks:
$.ajax( .. ).always(function(data) {
console.log(JSON.stringify(data));
});
Its contents will give you an understanding of what's wrong.
Need to remove , from dataType: "json",
dataType: "json"
The ajax URL must be the same domain. You can't use AJAX to access cross-domain scripts. This is because of the Same Origin Policy.
add "dataType:JSONP" to achieve cross domain communication
use below code
$.ajax({
URL: cross domain
dataType: 'jsonp'
// must use dataType:JSONP to achieve cross domain communication, otherwise done function would not called.
// jquery ajax will return "statustext error" at }).always(function(data){}
}).always(function(data){
alert(JSON.stringify(data));
}
A few things that should clear up your issue and a couple hints in general.
Don't listen for a click on a submit button. You should wait for the submit event on the form.
The data option for $.ajax isn't expecting a JSON string. It wants a serialized string or an array with name and value objects. You can create either of those easily with .serialize() or .serializeArray().
Here is what I was thinking for your script.
$('#form-with-loginSubmitButton').on('submit', function(e){
e.preventDefault():
var $form = $(this),
data = $form.serializeArray();
$.ajax({
type: "POST",
url: "/somewebservice/v1/users/authenticate",
data: data
}).done(function(result){
console.log(result);
});
});

Call similar to $.get in $.ajax

I have the following code:
$.get(url, {}, checkResponse)
And the following function:
function checkResponse(content) {}
The parameter "content" here is the result of the "get". I wanted to implement $.ajax to able to wait for the process to complete before it jump to the next chunk of code. I tried the following code but it didn't work.
$.ajax({
async: false,
type: 'GET',
url: url,
success: function (data) {
alert(data.toString());
checkResponse(data);
},
error: function (data) {
alert("error");
}
});
Here's what happened, the alert for the data.toString() gives empty string value while it should give me the url page content, and after it hits the alert it jumps to the error section and displays the alert "error".
According to the discussion in the comments section you are trying to send cross domain AJAX calls to arbitrary urls on the internet. Due to the same origin policy restriction that's built into the browsers this is not possible.
Possible workarounds involve using JSONP or CORS but since you will be sending requests to arbitrary urls that you have no control over they might not be an option. The only viable solution in this case is for you to write a server side script that you will host on your domain acting as a bridge. This script will receive an url as parameter and send an HTTP request to this url in order to retrieve the result. Then it will simply return the result back to the response. Finally you will send an AJAX request to your own server side script.

jQuery/Ajax IE7 - Long requests fail

I have a problem with IE7 regarding an ajax call that is made by jQuery.load function.
Basically the request works in cases where the URL string is not too long, but as soon as the URL gets very large it fails. Doing some debugging on the Ajax call I found this error:
URL: <blanked out security reasons but it's very long>
Content Type:
Headers size (bytes): 0
Data size (bytes): 0
Total size (bytes): 0
Transferred data size (bytes): 0
Cached data: No
Error result: 0x800c0005
Error constant: INET_E_RESOURCE_NOT_FOUND
Error description: The server or proxy was not found
Extended error result: 0x7a
Extended error description: The data area passed to a system call is too small.
As you can see, it looks like nothing is being sent. Now this only happens on IE7 but not other browsers, with IE8 there is a small delay but still works. The same request works fine when the URL string is relatively small.
Now I need this working on IE7 for compatibility reasons, and I cannot find workarounds for this.
The actual AJAX call is like this:
$("ID").load("url?lotsofparams",callbac func(){});
"lotsofparams" can vary, sometimes being small or very large. It's when the string is very large that I get the above error for IE7 only.
since load uses HTTP Get method, there is limit to the size of the url, which is 4KB as far as I know. So instead of GET, use $.ajax with HTTP Post option. Post has no limit.
use the following code.
$.ajax({
url: url,
type: "POST",
async: true,
data: {name1: value1, name2: value2, ...}, // put your data.
success: function(data, textStatus) {
$("ID").html(data);
}
});
Don't put the query string parameters into the the url.
The second parameter of .load() is made just for that. Should be:
$("ID").load("url", {
foo: "bar",
morefoo: "morebar"
},callbac func(){});
or you can use $.post()
$.post("url", {
foo: "bar",
morefoo: "morebar"
}, function(data){
alert(data);
});
Since the .load() will internally use a "POST" request when parsing an object, you might consider to replace it with $.get() if you require a "GET" request.
I ran into this same problem. I had been sending everything via the URL (long querystring) and it was failing. I found out the key was to send the data in its own parameter (dataparms, in this example) which is just the querystring section of the URL.
$.ajax({type: "POST", url: URL, data: dataparams, dataType: "html", async:false});

Categories

Resources