I've got some simple JS/jQuery code to make an AJAX call to grab some HTML and shove it into a div on my page. This works fine in Firefox but fails in Chrome.
In the Chrome console I can see the AJAX request shown with a status text of "(failed)" and type "pending".
All the searching I've done has searched is relating to cross-domain issues. This doesn't fit here, I'm running this on a webserver, with a domain name, without a port number appended.
Here's my code sample (you can see I was initially trying to use .load(), same problem):
$('#brochure2012navigation a').click(function(event)
{
event.preventDefault();
//$('#brochurePage').load($(this).attr('href'));
$.ajax({
url: $(this).attr('href'),
dataType: 'html',
success: function(html) {
$('#brochurePage').html(html);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr);
console.log(thrownError);
},
});
});
In Chrome's console the logged xhr object looks like this:
Object {readyState: 0, setRequestHeader: function, getAllResponseHeaders: function, getResponseHeader: function, overrideMimeType: function…}
abort: function (a){a=a||"abort",p&&p.abort(a),w(0,a);return this}
always: function (){i.done.apply(i,arguments).fail.apply(i,arguments);return this}
complete: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
done: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
error: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
fail: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
getAllResponseHeaders: function (){return s===2?n:null}
getResponseHeader: function (a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c}
isRejected: function (){return!!i}
isResolved: function (){return!!i}
overrideMimeType: function (a){s||(d.mimeType=a);return this}
pipe: function (a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()}
progress: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
promise: function (a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}
readyState: 0
responseText: ""
setRequestHeader: function (a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this}
state: function (){return e}
status: 0
statusCode: function (a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this}
statusText: "error"
success: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
then: function (a,b,c){i.done(a).fail(b).progress(c);return this}
__proto__: Object
Apologies that this looks a bit messy, but I think the important thing is the status of 0.
Monitoring the logs, the request isn't hitting my server.
I'm really stumped here, I'd appreciate any help!
Cheers,
Al
It is possible that the ajax call gets blocked by the AdBlock Chrome addon.
Some URLs might get blocked, based on the keys on the adblock blacklist.
On DevTools Network tab, such requests are marked as 'failed', in status 'pending'
You code seems perfect but some typos seen in your code, i added some of the other elems
$('#brochure2012navigation a').click(function(event){
event.preventDefault();
$.ajax({
url: $(this).attr('href'),
dataType: 'html',
async:false, // <------------------try with adding this
type:'post', // <------------------try adding this too
success: function(data) {
$('#brochurePage').html(data);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr);
console.log(thrownError);
} // <----------------------comma found here
});
});
or you might be get interest in this:
$('#brochure2012navigation a').click(function(event){
event.preventDefault();
$.ajax({
url: $(this).attr('href'),
type:'POST',
success: function(response, status, xhr){
var ct = xhr.getResponseHeader("content-type") || "";
if (ct.indexOf("html") > -1) {
$('#brochurePage').html(data);
}
if (ct.indexOf("json") > -1) {
// handle json here
}
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr);
console.log(thrownError);
}
});
});
I made a small change to your code:
var url = $(this).attr('href');
$.ajax({
url: url,
....
After that I set your code to work on a jsfiddle:
http://jsfiddle.net/kyz69/1/
I'm getting the content of /_display/ ( http://fiddle.jsshell.net/_display )
I'm linking to that because you didn't provide the url you're trying to load and that was the only page I could find that would return data because it's not cross domain.
I tested the code on Windows + Google Chrome Version 24.0.1312.52 m
Can you test the fiddle and post here the outcome?
could it be the trailing comma after the error function's closing brace? Usually you only would put a comma if there are additional objects...
I wish I have enough reputation to post a comment to ask for more details, but I don't. So I'll give my best guess by experience.
If it was a cross domain issue, Chrome would have logged an error message in the console in red. Test in this Fiddle.
One way I know that could help is to user a sniffer. Luckily Chrome have a simple one built in the Chrome Developer Tool, by pressing Ctrl + Shift + I, I guess you probably know this as you have copied the console output, but this time go to the Network tab, make sure it stays open when you click on the link that triggers this click event handler.
You'll see a new record shown in the table, click on its name, and you can take a look at the request and respond headers, or even rendered responds. Hopefully this will give you more helpful information as I usually get mine here.
Why you don't try this
$('#brochurePage').load($(this).attr('href'),function(){
alert('Load was performed.');
});
Good Luck!
Last attribute of ajax or json doesn't end with comma , no doubt it was failing in chrome & IE but why run good in firefox, I am stumped :), try this:
$('#brochure2012navigation a').click(function(event)
{
event.preventDefault();
//$('#brochurePage').load($(this).attr('href'));
$.ajax({
url: $(this).attr('href'),
dataType: 'html',
success: function(html) {
$('#brochurePage').html(html);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr);
console.log(thrownError);
}
});
});
Most browsers don't actually return any kind of interesting error if it is a cross-domain scripting issue. Any one I've used returns a StatusText of "error" and a readyState of 0, as you have shown. You may be thinking there is no crossdomain action happening because you are actually calling something from the same domain, maybe a different subdomain or a different port (https/non-https). It is possible you have an out-of-date version of Firefox that doesn't compensate for cross-domain restrictions. You can verify in your Chrome by looking in the Net request as past posters have suggested, and looking for the property: "Origin: null"
If indeed it turns out to be a cross-domain issue (I think it is), you will need to add the following line of PHP (or a similar header in the backend language of your choice) to the top of the file you are requesting, prior to any HTML code.
<?php header("Access-Control-Allow-Origin: example.com"); ?>
If you use jquery, you may also need:
<?php header("Access-Control-Allow-Headers: x-requested-with"); ?>
If your server isn't getting any request then problem must lie within the URL that you are using.
Are you typing the protocol and full URL or just partial?
What happens if you hard code a link and use it? (like follows)
$('#brochure2012navigation a').click(function(event)
{
event.preventDefault();
//$('#brochurePage').load($(this).attr('href'));
$.ajax({
url: $(this).attr('http://www.google.com'),
dataType: 'html',
success: function(html) {
$('#brochurePage').html(html);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr);
console.log(thrownError);
},
});
});
If i were you i would make sure that the $.ajax is really hitting its target by hardcoding a known target first.
If the hardcoded target isn't getting any request the problem lies somewhere else.
Related
I'm pretty new to ajax and I faced issue, that is not solvable by any of available stackoverflow's threads. I've got array with streams names and I use ajax to get detailed info about them by using Twitch API. For some of those requests I get following error:
Error: callback was not called
at Function.error (VM11084 jquery.min.js:2)
at b.converters.script json (VM11084 jquery.min.js:4)
at Nb (VM11084 jquery.min.js:4)
at A (VM11084 jquery.min.js:4)
at HTMLScriptElement.c (VM11084 jquery.min.js:4)
at HTMLScriptElement.dispatch (VM11084 jquery.min.js:3)
at HTMLScriptElement.q.handle (VM11084 jquery.min.js:3)
I found it peculiar that generated url (check url variable in code below) is ok and when I paste it in chrome's search bar, it leads to proper result. The most confusing part is that it works properly for 4 strings in streamsNames array and for others it does return this error code. I googled a lot however I cannot find proper solution or just explanation of this behaviour.
Here's the relevant part of the code:
function updateStreamInfo() {
streamsNames.forEach(function getStreamsCurrentData(streamName) {
var url = 'https://wind-bow.glitch.me/twitch-api/streams/' + streamName;
console.log(url);
$.ajax({
url: url,
dataType: 'JSONP',
jsonpCallback: 'callback',
type: 'GET',
success: function (data) {
console.log(data);
var stream;
if(data.stream === null) stream = new Stream(streamName, "", "");
else stream = new Stream(streamName, data.stream.game, data.stream.channel.logo);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(thrownError);
}
})
})}
And one more thing: this whole things runs in codepen.io but I do not know if that has any influence on anything in this case.
Any ideas what might be the issue?
Hi I just tried testing if the error function would return an alert but it didn't fire. I altered the url link hoping that it would generate an alert since it won't be able to find or get json data. All I am getting is "Uncaught TypeError: Cannot read property 'length' of undefined jquery-1.9.1.min.js:3"
$(document).on('pagebeforeshow', '#blogposts', function () {
//$.mobile.showPageLoadingMsg();
$.ajax({
url: "http://howtodeployit.com/api/get_recent_po",
dataType: "json",
jsonpCallback: 'successCallback',
async: true,
beforeSend: function () {
$.mobile.showPageLoadingMsg(true);
},
complete: function () {
$.mobile.hidePageLoadingMsg();
},
success: function (data) {
$.each(data.posts, function (key, val) {
console.log(data.posts);
var result = $('<li/>').append([$("<h3>", {
html: val.title
}), $("<p>", {
html: val.excerpt
})]).wrapInner('');
$('#postlist').append(result).trigger('create');
return (key !== 4);
});
$("#postlist").listview();
},
error: function (data) {
alert("Data not found");
}
});
});
I think the problem is that, when you make the AJAX request your code is executing the success callback, not the error callback. Thus when you execute:
$.each(data.posts, function(key, val) {
The $.each function is trying to get the length of data which is NULL.
It doesn't look right that you have defined a jsonp callback function and yet your still using the success and error callbacks. This SO question might help a bit :
Use of success / jsonpCallback with ajax request
Maybe here $.each(data.posts, data.posts is undefined and that's why you get an error. Log data in success callback and see what it contains.
I created a clean Fiddle. Opening the given URL gives a 301 redirect followed by a 200 JSON response. The HTTP status code says that everything is fine, so jQuery doesn't know there was an error.
You mixed up two different concepts here: jQuery's error callback is for network errors and all these things. If you transport error states inside your JSON with HTTP status code 200 you have to deal with it on your own inside the success callback.
Sorry, SO doesn't allow JS-Fiddle links without code:
beforeSend: function() { console.log('beforeSend'); },
complete: function() { console.log('complete'); },
success:function (data) { console.log('success') },
error: function(data) { console.log('error') }
Thanks everyone for your input. I did take on-board all suggestions. Recommendation from Jason seems to had made more sense so while investigating his suggestion I came to this site to read up more about jasonCallback. removing the jasonCallback option though did not fix the issue but strangely this issue seems to do with the url I was using for my json caalback.
What I then did was to change the url from "http://howtodeployit.com/api/get_recent_po" to "http://howtodeployit.com/category/daily-devotion/feed/?json=recentstories" and it worked. Even though both returned error in the console but the second was the one that triggered the error function. Why I am looking into it.
My calls to $.post are not working all over my code. I'm not sending the request to other domains and, actually, I'm doing everything localhosted. My localhost alias was automatically defined by the Mac OS X 10.8 as ramon.local and I'm requesting from http://ramon.local/linkebuy_0.7/resourceX to http://ramon.local/linkebuy_0.7/resourceY. There are no errors on Chrome's console.
The server side doesn't receive the request and I can check it by accessing directly from the browser (typing the URL).
It's not just one call that is not working, none of them are. They were all working days ago and I'm suspicious that I accidentally changed something on my local settings. What could it be?
Here's an example of what I'm facing:
$.post(
<<CORRECT URL INSIDE THE DOMAIN>>,
{},
function(response) {
console.log('THIS SHOULD BE PRINTED ON CONSOLE');
alert('THIS SHOULD BE POPPED UP');
}
);
I don't get the alert, neither the console message while running the code above. So I tried the following:
$.support.cors = true;
$.ajax({
url: "http://ramon.local/linkebuy_0.7",
dataType: "json",
type: "GET",
crossDomain: true,
success: function (data) {
console.log(data);
},
error: function (xhr, status, error) {
alert(error + " - " + status);
}
});
I just came with $.support.cors = true; and crossDomain: true to check if it was a cross domain issue. So I was alerted No Transport - error same way as before.
What can I do to solve that?
Thanks in advance.
Try this and see if you are getting any alert:
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.post("your url", function() {
alert("success");
}).success(function() {
alert("second success");
}).error(function() {
alert("error");
}).complete(function() {
alert("complete");
});
// perform other work here ...
// Set another completion function for the request above
jqxhr.complete(function() {
alert("second complete");
});​
Well, I solved the problem in a very strange way.
I deleted the JQuery file and downloaded it again, replacing the old one. Happens it worked out.
So, if you're:
Making AJAX requests that are not cross-domain;
Using JQuery for it (e.g. $.post, $.get, etc);
Getting No Transport AJAX error
Then re-download and replace you're JQuery source.
Else, if you're making cross-domain requests (not this case), then look for JSONP and try to set $.support.cors = true; at the beginning of you're code.
Thanks everyone for the comments and answers.
My problem happens to be the error, I am attempting to produce an error, in this case the error being hiding the loading symbol and showing a refresh button in order for the user to reload the page to see if the data loads this time.
$(document).ready(function () {
$('#busy').show();
$(document).bind('deviceready', function () {
var today = $('#todaysong');
$.ajax({
url: 'my url',
dataType: 'jsonp',
jsonp: 'jsoncallback',
timeout: 5000,
success: function (data, status) {
$.each(data, function (i, item) {
var song = '<name>' + item.name + '</name>' + '<artist>' + item.artist + '<br></artist>';
$('#busy').hide();
today.append(song);
});
},
error: function (error) {
$('#busy').fadeOut();
$('#reload').fadeIn();
}
});
});
});
This is my code, could someone advise on what I am doing wrong, I've tried a few things and cannot seem to get it to work, also would I make it so said button was able to refresh this individual piece of code?
Thanks a lot.
In order to debug your code:
Are you generating an error on your own? Is it really an error? Track your request via Firebug or ...
Be sure about running the error function. Again try Firebug or such things to set break points.
Check the JavaScript console for being sure there is no any of damn JavaScript error. And again Firebug error console.
Without seeing other details it is difficult to suggest.
Still I'm trying.. Check the IDs of the elements you have mentioned is same as they are in HTML. Check in HTML that one id is not assigned to more than one element.
In the AJAX code remove jsonp: 'jsoncallback', for a while and test if it is working.
error(jqXHR, textStatus, errorThrown)
A function to be called if the request fails. The function receives
three arguments: The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object, a
string describing the type of error that occurred and an optional
exception object, if one occurred. Possible values for the second
argument (besides null) are "timeout", "error", "abort", and
"parsererror". When an HTTP error occurs, errorThrown receives the
textual portion of the HTTP status, such as "Not Found" or "Internal
Server Error." As of jQuery 1.5, the error setting can accept an array
of functions. Each function will be called in turn. Note: This handler
is not called for cross-domain script and JSONP requests. This is an
Ajax Event.
Where the important part in this case is;
Note: This handler is not called for cross-domain script and JSONP
requests.
Quote from the API documentation of jQuery.ajax.
You should instead be using jsonpCallback.
The following call works perfectly in Chrome, but fails in every other browser.
function getInfo(r,c,f){
return $.parseJSON($.ajax({
url: baseURL + 'somethingAPI/getInfo',
data: {
"data_r": r,
"data_c": c,
"data_f": f
},
//success: function(data){},
dataType: "json",
async: FALSE
}).response);
}
Yes, I'm using a synchronous ajax call and I believe it is necessary as I don't want any of the other JS to run without this executing and returning data. Although, I'm not entirely sure if something else should be happening with the success callback.
Anyway, in Chrome I get the response object (JSON) and can access the data within just fine.
Does anyone know what I'm doing wrong?
Regarding your point about not knowing how to avoid async: false, is this something like what you're looking to accomplish?
function getInfo(r, c, f, callback) {
$.ajax({
url: baseURL + 'somethingAPI/getInfo',
data: {
"data_r": r,
"data_c": c,
"data_f": f
},
dataType: "json",
success: callback,
});
}
getInfo('foo', 'bar', 'baz', function(response) {
console.log(response);
});
Rather than parsingJson on the ajax query, here's the syntax I use to conquer these challenges
$.ajax({
url: "pagegoeshere.php",
timeout: 30000,
type: "POST",
data: 'data1='+data1+'&data2='+data2,
dataType: 'json',
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("An error has occurred making the request: " + errorThrown)
},
success: function(returnjson){
var returnstuff = returnjson.returnstuff;
//Do next Javascript step here
}
});
You can run ensuing javascript/jquery in the success and "stack" events together on success of your Ajax call. That way, if it works, it proceeds. Otherwise, the error handling can occur in the provided error section in a manner that you define. I generally fire my ajax calls on a click handler, but it's certainly doable to run it in a function as you have chosen. Be sure to check your return JSON (could be mailed from your processing page, for example) to make sure it's valid JSON. Jsonlint is your friend!
I've had chrome effectively parse bad HTML and JSON while the other browsers don't on several occasions. I'd suspect it's something along those lines that's specifically causing your issues.