I have a really simple chat application on a site which works pretty good.
It requests by ajax like this:
$.ajax({
url: "fetch/"+CHAT_SESSION_ID+"/"+LAST_MESSAGE_ID,
dataType: "json",
cache: false,
success: function(data) {
if (data.session_active == 0) { //If other chatter ended session
alert("Session Ended");
}
else
{
$.each(data.messages, function(i,msg){
alert(msg.message.Body);
)};
}
}
});
and gets a json response that lookes like this:
{ "session_active": "1", "messages": [ {"message": {"MsgID": "100", "UserID": "1", "Body": "heyy"}}, ]}
It works really well in at least FF and Saf but in Chrome it never gets past the .each!
This is driving me nuts, have tried everything I've come across online for days but I can't seem to get it right.
Please someone help! I can provide testserver if someone wants to firebug it themselves ;)
Perhaps the trailing comma in your messages array is causing an issue. See the responses to the following question:
Can you use a trailing comma in a JSON object?
Possible incorrect mimetype: If you look at jQuery's parsing code, it seems that if the JSON data isn't a string passed to $.parseJSON(data) then it returns null. This might be a problem as if the AJAX response's mimetype is incorrectly identified by Chrome and it doesn't interpret the AJAX response as text, it'll return null and therefore pass null to the AJAX function. The mimetype served with the AJAX response (or possibly lack of one) may therefore also be the problem:
parseJSON: function( data ) {
if ( typeof data !== "string" || !data ) {
return null;
}
// Make sure leading/trailing whitespace is removed (IE can't handle it)
data = jQuery.trim( data );
// Make sure the incoming data is actual JSON
// Logic borrowed from http://json.org/json2.js
if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "#")
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
.replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
// Try to use the native JSON parser first
return window.JSON && window.JSON.parse ?
window.JSON.parse( data ) :
(new Function("return " + data))();
} else {
jQuery.error( "Invalid JSON: " + data );
}
},
Malformed JSON: The other reason why this might work in Firefox and other browsers but not Google Chrome is the jQuery parse function tries to use the native window.JSON.parse(data) function over new Function("return " + data) if native JSON parsing is available in that browser.
Google Chrome's parsing may be more strict than Firefox is at having things like trailing commas as specified by the standard at http://www.json.org/ as stated in Danilo Celic's answer.
Related
This is my first Stack Overflow question as a newly-employed junior developer. I have done a lot of searching but can't seem to find an answer, apologies if I have missed it.
I have a couple of large JavaScript objects that I am looking to pass from the frontend of a web app to the C# backend. With the app I'm working on, we have been using JSON.stringify(object) to prepare data to pass to the backend. When it hits the backend we do ApplyMyData data = JsonConvert.DeserializeObject<ApplyMyData>(json); - no issues normally.
EDIT: Here's how we post:
$.ajax({
type: 'POST',
url: '/Controller/MyMethod',
data: {
json: JSON.stringify(myObject)
},
success: function (response) {
if (response.success) {
// yay
} else if (response.success === false) {
// nay
} else {
alert('Something unexpected happened');
}
}
});
'Why not just keep using JSON?' I hear you ask!
Well, that's tricky. Thanks to client requirements, we must support IE11, which seems to have a limit on the size of strings. Reference:
What is the maximum possible length of a query string?
Therefore, the resulting JSON.stringify(object) is incomplete/invalid and when it's parsed, an error is thrown. We have no issues when users are on Chrome.
I have done up a quick fiddle to demonstrate this problem, try run it in Chrome and then IE11, then look at the console logs and you'll see what I am getting at:
https://jsfiddle.net/8yx7bqjs/.
IE11 truncates the string length at 1024 characters... sigh...
So to my questions:
Is there another way I can send the JavaScript object 'unmodified' -or- 'unstringified' to the backend instead?
Must all data sent to backend be in the form of a string?
Is there a workaround for IE11 that can let you work with strings longer than 1024 characters? I can't seem to find any.
Thanks in advance.
You can make mock ajax requests in Fiddle.
heres what I looked at really quickly:
https://jsfiddle.net/8yx7bqjs/1/
$.ajax({
type: 'POST',
url: '/echo/json',
data: {
"stuff": myArray
}
}).done(function(res){
console.log("success");
}).fail(function(res){
console.log("test failed")
});
IE11 is showing no problems with actually sending the data.
Depending on the actual length of your string ASP.Net has a limitation of 102400 by default.
Thanks #robjam, this has helped me a lot. I'm using Raygun for error reporting and gives me with the POST form value. The form value is truncated in their console so I thought (probably wrongly) that the string was being truncated in the browser before it actaully gets POST-ed to the backend.
But looks like IE11 is stringifying just fine, maybe RayGun simply isn't printing out all the JSON in their error logging console which has thrown me off the scent.
Will investigate further, thanks.
I'm working on a project and use ajax to update some informations in forms.
Here is my ajax function :
function update_ad() {
var project_name = document.getElementById("mol_project").value;
if (project_name !== '') {
$.ajax({
type: 'POST',
url: "controllers/get_project.php",
data: {project_name: project_name},
dataType: 'text',
success: function (data) {
var result = JSON.parse(data);
}
});
}
}
On my development environement everything works fine. The function get the json text from php server and parse it so I can use data after that.
But on my production environement, I receive a parsing error :
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Here is the received Json :
{"project_name":"Jaguar","project_ORB_code":null,"project_manager":null,"project_abbr":"JR","project_mol_index":"2","project_comment":null}
Jquery, apache and php version are the same on both environements. I guess it's a server configuration issue but I can't figure out where it is.
replace dataType: 'text' to dataType: json,
Look at the spec for JSON (easily understood version here: http://json.org/). There is nowhere that says that parenthesis are valid. ({"foo": true}), for example will never parse. It may be evaled as it is valid javascript, but javascript is not JSON.
Okay, in your JSON, there's a UTF-8 BOM in the front. Can you find the difference between:
{"project_name":"Jaguar","project_ORB_code":null,"project_manager":null,"project_abbr":"JR","project_mol_index":"2","project_comment":null}
And:
{"project_name":"Jaguar","project_ORB_code":null,"project_manager":null,"project_abbr":"JR","project_mol_index":"2","project_comment":null}
Where the latter is a valid JSON. Check it out with JSONLint. You need to make sure that the output you are receiving is free of UTF-8 BOM.
When I tried using the encodeURI() function on the JSON, it gave me this output:
encodeURI(' {"pr'); // "%20%EF%BB%BF%7B%22pr" - Wrong one!
encodeURI(' {"pr'); // "%20%7B%22pr" - Correct one!
We can make use of encodeURI to detect the anamolies and fix it in the client side. I am working on a solution.
The unicode signature, if you see, is EF BB BF, which is explained in this article. We can make use of this signature and try to correct it.
If you have the access to the PHP source, try setting the right headers:
header("Content-type: application/json; charset=utf-8");
I'm using $.post to send a form via ajax to a PHP page, which returns JSON data. Once upon a time, it worked perfectly, and the function(data) executed as normal. Somehow, I've broke it, and now it doesn't even touch the function(data). I've tried undoing most of what I've done, but I still can't find the problem.
Here's the script :
$("#modifyhome").submit(function(event) {
if($("#modifyhome").valid()) {
event.preventDefault();
var $form = $( this ),
title = $form.find('input[name="title"]').val(),
content = $form.find('textarea[name="content"]').val();
$.post("?action=page-accueil", {"title": title, "content": content},
function(data) {
if(data['error'] == 1)
{
$().message(data['message']);
$("div.jquery-message").effect("shake", {times: 3}, 900);
}
else if(data['error'] == 0)
{
$().message(data['message']);
$("div.jquery-message").effect("bounce", {times: 3}, 900);
}
else
{
$().message("Erreur de connexion au serveur : veuillez réessayer.");
$("div.jquery-message").effect("shake", {times: 3}, 900);
}
}, "json"
);
}
else
{
$("[id^=qtip-]").effect("pulsate", {times: 3}, 600);
return false;
}
});
And here is what the PHP page (?action=page-accueil) returns :
{"error":0,"message":"Page modifiée."}
That all checks out as valid JSON, but it's as if jQuery doesn't recognize it for some reason. Any help is greatly appreciated :)
You're not clear about what the problem is. At the beginning you say
Somehow, I've broke it, and now it doesn't even touch the function(data)
but then you say that jQuery is not recognizing your JSON, which means the callback function was invoked. You need to test each phase of the process to discover your error. Browser console is a must for debugging in this case.
Test cases:
is the server returning anything? If not
Is there an error in the php code? May return 500 error or could return OK, but with error message as string.
Is there a same-origin issue? Perhaps going form HTTP -> HTTPS?
If the server is returning something but it is not being parsed correctly.
Is the data being returned valid JSON? For PHP you should use json_encode function if available or something similar. jQuery side there is jQuery.parseJSON()
Is there an issue with response-type headers? In this case you will want to use normal $.ajax and set the beforeSend parameter to something like beforeSend: function(xhr){ xhr.setRequestHeader("Accept", "text/javascript") }. You will need to further research this option.
To test any of this it is fundamental that you are familiar with the browser console. Chrome Network Panel or Firebug Net Tab
I used to get this problem too, I am exactly not sure of the reason why. But I have a solution that works.
$.post("?action=page-accueil",
{"title": title, "content": content},
function(data) {
data = eval("("+data+")");
//.... Then continue it
});
Or, use .parseJSON() function to read the string as JSON, if you dont want to use eval()
$.post("?action=page-accueil",
{"title": title, "content": content},
function(data) {
data = $.parseJSON(data);
//.... Then continue it
});
I am trying to make a firefox extension that will list all the videos on a page. I had already got it working as a normal js script (not as an extension) so I know the script works.
My problem is that the $.ajax inside my firefox extension doesn't get called at all. If I look at the error console it shows a message like "unsafe use of Jquery". I've tried searching Google and other sites but I couldn't come up with a solution.
Here's the code where the problem is:
var listMainVid = function ()
{
// Make a JSONP call. We are using JSONP instead of JSON because we have to make a cross-domain AJAX call
$.ajax({
url: vidinfo_q_url + "?jsoncallback=?", // Don't forget to put in the 'jsoncallback=' part
dataType: 'jsonp', // Make a JSONP request, have it received as text, and interpreted by jQuery as JSON: "jsonp text xml."
data: {
video_url: '' + doc.document.location
},
success: function ( data, textStatus, jqXHR ) // Keep in mind that this is just the request sending success.
{
if ( data.status === 'SUCCESS' )
{
var vid_loc = data.url, img_url=data.image_url;
if( Object.prototype.toString.call( vid_loc ) === '[object Array]' ) // Check if it's an array
vid_loc = data.url[0];
if( Object.prototype.toString.call( img_url ) === '[object Array]' ) // Check if it's an array
img_url = data.image_url[0];
addVideoToVidDiv( data.id, vid_loc, img_url );
}
else // Error
{
//alert ( " Error! Data=" + data.status );
}
afterMainVid();
},
error: function( xhRequest, ErrorText, thrownError )
{
Application.console.log( " Can't do because: " + ErrorText + ", " + thrownError );
afterMainVid();
}
});
afterMainVid();
}
Any help/pointers would be greatly appreciated.
OK, I finally figured it out on my own. This is to anyone else who might run into the same problem. Change the dataType: 'jsonp', TO dataType: 'json', And that's it! I don't know why but FF doesn't seem to support 'jsonp' calls from inside extensions. One thing to note here is that inside FF extensions, you don't need 'jsonp' anyway as the extensions are free to make cross-domain ajax calls. Hope this will help.
Have you fully installed the extension? You can't just execute the .xul file, you have to install it properly to let Firefox know you "trust" the extension before letting it do stuff like AJAX requests.
OK, as SomeKittens requested, I am answering my own question (didn't know I could do that).
The solution to the problem is to change the dataType: 'jsonp', To dataType: 'json'.
I don't know why but FF doesn't seem to support 'jsonp' calls from inside extensions. One thing to note here is that inside FF extensions, you don't need 'jsonp' anyway as the extensions are free to make cross-domain ajax calls. Hope this will help.
I've also provided the answer in the question itself.
What the best way to report a syntax error when I'm loading a JSON feed with jQuery? I can establish the error reporting settings like this:
error: function(xhr){
alert('Request Status: ' + xhr.status + ' Status Text: ' + xhr.statusText + ' ' + xhr.responseText);
}
however this function doesn't fire when the URL I've called loads a valid page (albeit not one with a JSON object in it). Futhermore, I can't check the data that it does return because (according to Firebug at least) jQuery.getJSON breaks at the syntax error before it passes the object to the function that executes it.
The reason I'd like to report errors is because this is my way of checking whether the user has supplied a URL that will produce a valid JSON feed.
Here's a related answer that requires control over what the server will respond with.
Here's the syntax error that Firebug gives me
The syntax error Firebug gives me http://img.skitch.com/20090623-8c97g47jha4mn6adqqtjd41cwy.jpg
Any ideas? Thanks
You can bind a function to global ajaxerror events$(document).ajaxError(function(event, request, ajaxOptions, thrownError){
if ( 4==request.readyState) { // failed after data has received
alert(ajaxOptions['url'] + " did not return valid json data");
}
else {
alert("something else wnet wrong");
}
});
or use $.ajax() instead of $.getJSON()function foo() {
// $.getJSON("http://localhost/test.txt", function(data){});
$.ajax({
type: "GET",
url: "http://localhost/test.txt",
success: function (data, textStatus) {
alert("succuess");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("request failed: " + textStatus);
},
dataType: "json"
});
}
edit: But you might want to keep in mind that both ajax(dataType:"json") and getJSON() (which simply invokes .ajax(dataType:"json") boil down to data = window["eval"]("(" + data + ")") ...this might not be what you want if you don't know what (arbitrary) data your script requests. And this could explain why firebug is catching a syntax error when you feed it an html document instead of json data.
In that case better request dataType:"string" und run the data through a fully fledged json parser lib.
Thanks to all who answered. Because I was calling a JSON feed from an external domain, I wasn't able to just use jQuery's AJAX functionality and pull the feed as "text" instead of "json". jQuery only allows you to pull "json" and "script" from a remote source.
What I ended up doing instead was writing a PHP script to make the external call that lived on my own server. I use jQuery AJAX to call this, pass the requested source in the URL, and then grab that as "text." I then run my own check to ensure that it's properly formatted JSON, and then parse it with another library. jQuery doesn't have the ability to parse JSON at the moment; $.getJSON only works if you pass a URL to it.
Call the URL or the XHR request directly in your browser's address bar, do a view-source and paste the result into and IDE that understands JavaScript. You'll probably spot a misplaced quote or something.
At least you'll be able to remove chunks of it until you find the offending syntax if nothing else.
Adding to Diodeus' answer, paste your potentially offending JSON into here this tool: http://jsonformatter.curiousconcept.com/
If you have firebug, you might even be able to hack together a way to use the site a service programmatically, though that may be frowned upon.