IE7 not digesting JSON: "parse error" - ajax

While trying to GET a JSON, my callback function is NOT firing.
$.ajax({
type:"GET",
dataType:'json',
url: myLocalURL,
data: myData,
success: function(returned_data) {
alert('success');
}
});
The strangest part of this is that:
my JSON(s) validates on JSONlint
this ONLY fails on IE7...it works in Safari, Chrome, and all versions of Firefox, (and even in IE8). If I use 'error', then it reports "parseError"...even though it validates!
Is there anything that I'm missing? Does IE7 not process certain characters, data structures (my data doesn't have anything non-alphanumeric, but it DOES have nested JSONs)? I have used tons of other AJAX calls that all work (even in IE7), but with the exception of THIS call.
An example data return here is: (this is a structurally-complete example, meaning it is only missing a few second-tier fields, but follows this exact hierarchy)
{"question":{
"question_id":"19",
"question_text":"testing",
"other_crap":"none"
},
"timestamp":{
"response":"answer",
"response_text":"the text here"
}
}
I am completely at a loss. Hopefully someone has some insight into what's going on...thank you!
EDIT
Here's a copy of the SIMPLEST case of dummy data that I'm using...it still doesn't work in IE7.
{
"question":{
"question_id":"20",
"question_text":"testing :",
"adverse_party":"none",
"juris":"California",
"recipients":"Carl Chan"
}
}
I am starting to doubt that it is a JSON issue...but I have NO idea what else it could be. Here are some other resources that I've found that could be the cause, but they don't seem to work either:
http://firelitdesign.blogspot.com/2009/07/jquerys-getjson.html (Django uses Unicode by default, so I don't think this is causing it)
Anybody have any other ideas?

The example data you present looks all right but my strong suspicion still is that there is an unclosed comma somewhere like this:
"timestamp":{
"response":"answer",
"response_text":"the text here"
}, <------------
}
IE is the only browser that (correctly) trips over this.
If this is not it, can you show a full data sample (or confirm that the example you show is indeed a full sample)?

Did you already exclude the possibility of a caching issue?
e.g. you tested with IE7 when myLocalURL returned invalid json. IE7 still caches that response and thus it doesn't work. Try adding something like this (e.g. if php) to myLocalURL or make myLocalURL look like myLocalURL?random=123 just for testing to make sure it isn't a caching thing
header("Cache-Control: no-cache, must-revalidate");
header("Expires: 0");
Are you returning a correct content-typ header? e.g.
header("Content-Type: application/json");

I've just encountered exactly the same issue. It turns out that IE7 fails to parse JSON responses that have leading \r\n line feeds in the response body. Your fix of removing {% load customfilter %} works because you removed the new line that was being included after this tag.
An alternative fix would be to just remove the new line to get
{% load customfilter %}{ "question":{ "question_id":"{{question.id}}",
"question_text":"{{question.question_text|customfilterhere}}"
}
}

Related

Conflict between EJS and Marionette

For my single page application, the page is delivered by node-express-ejs on the server side to Maironette-Backbone based client on the browser. Unfortunately, both EJS and Marionette use the syntax "<%= var %>" for plugging in computed values. My page has some values that need to be plugged in by the server and some that will be computed by the client. So I need something like the following snippet to work.
<html> .....
Server Computed = $ <%=serverComputed%>
Client Computed = $ <%=clientComputed%>
....</html>
And my routes.js on the server would have something like,
res.render('test', { serverComputed: '5000' });
But, EJS throws
ReferenceError: .../test.ejs:17
.....
clientComputed is not defined
The following does not help either
res.render('test', { serverComputed: '5000', clientComputed: '<%= clientComputed %>' });
since it as expected, ends up as
$lt:%= clientComputed %>
Is there a way (a market, a processor directive etc) to tell EJS processor to not process a part of the file?
Is there any other way to work around this conflict?
Thanks,
Hemant
Found the solution.
EJS does allow defining your own tags by setting them in the options. So far as I can tell, this is not documented. I only found it by going through the source code. Anyway, the following option setting would avoid conflict with Marionette open-close tags.
On server side, routes.js can specify options like this.
res.render('test', { open: '{{', close: '}}', serverComputed: '5000' });
In the ejs file, now you can have different markups for server-computed and client-computed variables, like so.
Server Computed = $ {{=serverComputed}}
Client Computed = $ <%=clientComputed%>
EJS processor will not process the "<%=clientComputed%>" part.
Hemant

can't get d3.xml to POST correctly

I tried to POST/GET some Vars to a php-file via AJAX/d3.xml, but a print_r($_POST/$_GET) inside the php, tells me they're empty. Even the example on the doc won't work for me.
d3.xml("xxx.php")
.header("Content-Type", "application/x-www-form-url-encoded")
/*
.get("a=2&b=3", function(error, data) {
console.log(error);
})
*/
.post("a=2&b=3", function(error, data) {
console.log(error);
})
.on("load", createTable(data));
The console tells me that there is a POST request but under POST (on Firefox, not on Chrome) it lists the Vars in one line "a=2&b=3", instead of
a = 2
b = 3
as it usually does. What is it that I'm not getting?
First, apologies for the confusion in the comments. I was looking at the source for an old version of d3. In the newer code, it is indeed true that if you do not provide a callback to d3.xml it returns an xhr request that you can configure directly. (If you do provide a callback, it executes a GET right away as before).
You're going to hate this, so get ready. :) Your issue is because you have an extra dash in your Content-Type header. You have:
application/x-www-form-url-encoded
but it should be
application/x-www-form-urlencoded
Looking at a modified version of your jsfiddle in Firefox, I see the arguments show up in the list view as expected: http://jsfiddle.net/WaT6r/3/

Google javascript API returns 404's

I have the same code (more or less) working fine in Java, but when I write it in javascript, I end up with 404's. I can't figure out what I'm doing wrong and it's driving me crazy!
gapi.client.load('translate', 'v2', function () {
gapi.client.language.languages.list().execute(function (response) {
response.data.forEach(function(language){
console.log(JSON.stringify(language));
});
});
"language":
{"code":404,"message":"Not Found","data":[{"domain":"global","reason":"notFound","message":"Not Found"}],"error":{"code":404,"message":"Not Found","data":[{"domain":"global","reason":"notFound","message":"Not Found"}]}}
I can see in the console the following POST data to https://content.googleapis.com/rpc?key=MY_API_KEY:
[{"jsonrpc":"2.0","id":"gapiRpc","method":"language.languages.list","apiVersion":"v1"}]
Should that say v1?
By contrast, the REST URL is https://www.googleapis.com/language/translate/v2/languages?key=MY_API_KEY (and it's a GET) and it works fine.
You are right that this was a bug in gapi.client.load. This bug has been fixed and you should no longer run into 404s.

MooTools AJAX Request on unload

i'm trying to lock a row in a db-table when a user is editing the entry.
So there's a field in the table lockthat I set 1 on page load with php.
Then I was trying to unlock the entry (set it 0) when the page is unloaded.
This is my approach. It works fine in IE but not in Firefox, Chrome etc....
The window.onbeforeunload works in all browsers, I tested that.
They just don't do the Request
BUT
if I simple put an alert after req.send(); it works in some browsers but not safari or chrome. So I tried putting something else after it just so that's there's other stuff to do after the request but it doesn't work.
function test() {
var req = new Request({
url: 'inc/ajax/unlock_table.php?unlock_table=regswimmer&unlock_id=',
});
req.send();
alert('bla'); // ONLY WORKS WITH THIS !?!?!?
}
window.onbeforeunload = test;
i've already tried different ways to do the request but nothing seems to work. And the request itself works, just not in this constellation.
ANY help would be appreciated!
Thanks
the request is asynchronous by default. this means it will fork it and not care of the complete, which may or may not come (have time to finish). by placing the alert there you ensure that there is sufficient time for the request to complete.
basically, you may be better off trying one of these things:
add async: false to the request object options. this will ensure the request's completion before moving away.
use an image instead like a tracking pixel.
move over to method: "get" which is a bit faster as it does not contain extra headers and cookie info, may complete better (revert to this if async is delayed too much)
you can do the image like so (will also be $_GET)
new Element("img", {
src: "inc/ajax/unlock_table.php?unlock_table=regswimmer&unlock_id=" + someid + "&seed=" + $random(0, 100000),
styles: {
display: "none"
}
}).inject(document.body);
finally, use window.addEvent("beforeunload", test); or you may mess up mootools' internal garbage collection

How sophisticated should my Ajax code be?

I have seen simple example Ajax source codes in many online tutorials. What I want to know is whether using the source code in the examples are perfectly alright or not?
Is there anything more to be added to the code that goes into a real world application?
What all steps are to be taken to make the application more robust and secure?
Here is a sample source code I got from the web:
function getChats() {
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null) {
return;
}
var url="getchat.php?latest="+latest;
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
function GetXmlHttpObject() {
var xmlHttp=null;
try {
xmlHttp=new XMLHttpRequest();
} catch (e) {
try {
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
The code you posted is missing one important ingredient: the function stateChanged.
If you don't quite understand the code you posted yourself, then what happens is when the call to getchats.php is complete, a function "stateChanged" is called and that function will be responsible for handling the response. Since the script you're calling and the function itself is prefixed with "gets" then I'm pretty sure the response is something you're going to be interested in.
That aside, there are a number of ways to improve on the code you posted. I'd guess it works by declaring a single "xmlHttp" object and then making that available to every function (because if it doesn't, the stateChanged function has no way of getting the response). This is fine until you run an AJAX request before the last one (or last few) haven't replied yet, which in that case the object reference is overwritten to the latest request each time.
Also, any AJAX code worth its salt provides functionality for sucess and failure (server errors, page not found, etc.) cases so that the appriopiate message can be delivered to the user.
If you just want to use AJAX functionality on your website then I'd point you in the direction of jQuery or a similar framework.
BUT if you actually want to understand the technology and what is happening behind the scenes, I'd continue doing what you're doing and asking specific questions as you try to build a small lightweight AJAX class on your own. This is how I done it, and although I use the jQuery framework today.. I'm still glad I know how it works behind the scenes.
I would use a framework like DOMAssistant which has already done the hard work for you and will be more robust as well as adding extra useful features.
Apart from that, you code looks like it would do the job.
I would honestly recommend using one of the many libraries available for Ajax. I use prototype myself, while others prefer jQuery. I like prototype because it's pretty minimal. The Prototype Ajax tutorial explains it well. It also allows you to handle errors easily.
new Ajax.Request('/some_url',
{
method:'get',
onSuccess: function(transport){
var response = transport.responseText || "no response text";
alert("Success! \n\n" + response);
},
onFailure: function(){ alert('Something went wrong...') }
});

Resources