Problem with Javascript, AJAX & JSON - php

I'm an iPhone Developer whose quite new to web development so please forgive me if I'm making silly mistakes here:
What I'm trying to accomplish is when the user selects an item from a drop-down, it calls some javascript, which sets off an AJAX request to a PHP file I have which returns some JSON. - That JSON includes a thumbnail image filename, and a caption for the image. These need to be passed in to an image, and textfield respectively in my document.
The problem is, it fails after trying to eval the json. - The same happens with eval(json); and JSON.parse(json); I worked this out by calling document.write('something'); periodically in my response method. - It will always be able to write up to the point where it parses the json.
I am sure my PHP is valid and my request is good (I can output the response from the JS fine).
Here is the function I call when a new item is selected in the drop-down:
function changeImage(id){
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var res=xmlhttp.responseText;
var responseObject = eval(res);
var caption = responseObject.caption;
var textField = document.getElementById('caption');
textField.value = caption;
var imagePreview = document.getElementById('imgPreview');
imagePreview.src = responseObject.filename;
}
}
xmlhttp.open("GET","getCaption.php?id="+id,true);
xmlhttp.send();
}
When I output res (or access the php file manually) the JSON looks like this:
{"caption":"A caption","filename":"myimage_thumb.jpg"}
why is the JSON eval failing?
UPDATE:
This error is logged: SyntaxError: Parse error

You're taking a JSON string and pretending that it's a Javascript object literal. But, remember, JSON is merely named after Javascript's object notation!
You're then hoping that eval will directly evaluate this and return an object, but this is not the case.
Observations
Writing the following in the Firebug console:
eval('{"caption":"A caption","filename":"myimage_thumb.jpg"}')
will also yield a SyntaxError. (Ideally, you'd have narrowed your problem down to this!)
Interestingly, constructing an object more explicitly does work (for this input):
eval('new Object({"caption":"A caption","filename":"myimage_thumb.jpg"})')
As does just forcing the input into being a certain kind of expression, with parentheses:
eval('({"caption":"A caption","filename":"myimage_thumb.jpg"})')
Explanation
It all comes down to this statement from 12.4 in the ECMAScript standard:
Note that an ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block.
This article explains the issue in depth, but in summary the solution is to use JSON.parse(res) to obtain an object from a JSON string. This is the proper approach, and it will not fail as long as your input is valid JSON.

Change the eval-line against:
eval('var responseObject = ' + res);

You might want to try:
eval("(" + res + ")");
so that it wraps it in (...). I'm not sure why yet.
Anyway, you could also look into jQuery, because then it's as simple as:
$.getJSON("path", function(json) {
// json is the ready-to-use object
});

There are a couple of suggestions that I would give in this context
Can you try doing a console.log(res) or alert(res), so that you know you really have a res before you try using it.
Never use eval(res). Why not use JSON.parse(res) (on modern browsers, since you have IE5 browsers too up there), or even better $.parseJSON (if using jQuery)
If you are sending if from PHP, use json_encode($var, JSON_HEX_TAG|JSON_HEX_APOS) to prevent syntax errors while parsing. Check my answer (link below) in another thread.
How to store a php array on the client side?

This is how I use eval -
var rsltObj = eval('(' + jsonStr + ')');

Related

Using AJAX for GET data from other server on Mouse Over

I am searching for this from yesterday, Do not know, I am unable to implement, or going in wrong direction.
My currently ajax function which is working with local server
function tooltipajax(r_ID)
{
var str ;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById('span'+ r_ID).innerHTML = xmlhttp.responseText ;
}
}
xmlhttp.open("GET","accounteditajax.php?key=" +r_ID,true);
xmlhttp.send();
}
PHP code:
print("<tr bgcolor=\"#EEEEEF\">");
print("<td class='normal' id=\"serialno\" onMouseOver='tooltipajax(this.id)'>
<a class=\"tooltip\" >Serial Number <span id=\"spanserialno\"
class=\"custom info\"></span> </a></td>");
print("<td bgcolor = \"#FFFFFF\" ><b>$serial</b></td>\n");
print("</tr>\n");
How can I get data from another server?
xmlhttp.open("GET","accounteditajax.php?key=" +r_ID,true);
I want to get from
http://iphere/filename.php
If you use use jQuery like so, this works.
function tooltip_ajax(r_ID) {
$.ajax({
url: "http://iphere/filename.php?id=" + r_ID,
context: document.body,
success: function(data) {
if(data) {
$('span' + r_ID).html(data);
}
}
});
}
That's tested with a different server and it works.
In order to retrieve data from another server using AJAX, you will need to utilize JSONP. This is due to Cross-Domain restrictions on AJAX requests. To expand on this further, if you wanted to make an AJAX request from a page located at http://test1.com, to a page / script located at http://test2.com, you would not be allowed.
Check out this article for more information: http://www.jquery4u.com/json/jsonp-examples/
Basically, JSONP involves adding a temporary SCRIPT tag to the page, which CAN load external content. The URL for this SCRIPT tag contains data, and a callback function name. The JSONP should then respond with the data, enclosed in a call to that function. Of course, the one downside is that the target server must support JSONP requests.
One alternative is using a bridge PHP script locally, that utilizes CURL to make the request, and return the information to your page, via AJAX.
For a bit more information regarding utilizing CURL in PHP, take a look at this article: http://codular.com/curl-with-php

javascript commands not executing after ajax loads PHP file

I have a PHP script being executed by AJAX, the PHP script loads everything fine except for js scripts in the actual PHP file which I am using to close divs(if the PHP file isnt run via AJAX all the scripts work FYI)..
this is the script not being run in the PHP file by ajax
echo "<script> closeOne('" . $postid . "'); </script>";
The JS scripts to close divs are included in the header of the page
This is the AJAX script I am using
<script type="text/javascript">
function mainload(str)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest(str);
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("loadmain").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","mainload.php?page="+str,true);
xmlhttp.send();
}
</script>
Any help would be appreciated.
JS in the ajax response is not executed by default. You have to parse and identify JS statements, then run them using eval function of js. See this code as an example to start your own code:
var sc=xmlhttp.responseText;
sc=sc.replace(/[\n\r\t\v\u00A0\u2028\u2029]{1,}/gm, ''); //Remove all types of White Space
sc=sc.match(/<.*?script.*?>.*?<\/.*?script.*>/gm); //divide into array, all the script tags
Then you will loop each of the 'sc' and run the following in the loop:
abc=loop_var.replace(/<.*?script.*?>(.*?)<\/script>/gm, "$1"); //remove script/open close tags and get JS only
eval(abc);
If you add script element to innerHTML of a DOM element, JS wont run immediately.
because that script element is just added.
and that tag is not going to get parsed at all.
Ideally you should send a response in form of a JSON wrapped function.
You can send output like this from the PHP page.
echo "(function(){ closeOne('" . $postid . "'); })";
In response, you could evaluate this String containing the function using eval.
codeToExecute = eval(xmlhttp.responseText);
then call the function,
codeToExecute();
Note: sending functions from server and directly executing it using eval could be a security concern.
be careful and better use some JS libraray function to evaluate the string into a JSON object.
There will be String-To-JSON convertersin jQuery,prototype and sencha's libraraies.
Better use them or if the browser supports, JSON.parse is also a good option.
But I hope the concept is clear to you.
Alternatively,
You could just send the post id from server in a JSON and call closeOne on the response like this:
in PHP,
echo "{post_id:".$postid."}";
and when the response comes,
responseObject = eval("("+xmlhttp.responseText+")");
closeOne(responseObject.post_id);

AJAX Update Mysql Table with Two PHP Variables

I am attempting to update a mysql table with PHP variables using AJAX.
Here is the PHP code that echos my variables:
<input type='button' name='button' class='bluebutton' value='Overnight Stay' onclick='callAjax($id1&$newName);' />
Here is my jquery:
var xmlHttp
function callAjax(id) {
if (id.length==0) {
document.getElementById("txtHint").innerHTML=""
return
}
xmlHttp=GetXmlHttpObject()
if (xmlHttp==null) {
alert ("Browser does not support HTTP Request")
return
}
var url="gethint.php"
url=url+"?id="+id
url=url+"&name="+name
xmlHttp.onreadystatechange=stateChanged
xmlHttp.open("GET",url,true)
xmlHttp.send(null)
}
function stateChanged(){
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
{
document.getElementById("txtHint").innerHTML=xmlHttp.responseText
}
}
function GetXmlHttpObject() {
var xmlHttp=null;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e) {
// Internet Explorer
try {
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
here is gethint.php. right now I am just echoing back the variables.
$id = $_REQUEST['id'];
$name = $_REQUEST['name'];
echo $id;
echo $name;
when I put it all together, I am getting an object expected error in the console which states:
Message: Expected ')'
Line: 3
Char: 21
Code: 0
URI: ../scripts/clienthint.js
this error corresponds to the lines 'function callAjax(id)'
I am stuck on stupid as to how I should call this one out.
I would appreciate any feedback anyone cares to make, no matter how critical.
Thanks Again,
--Matt
I don't have a clear answer, cause I suppose (see point 1) that the error message is misleading.
I suppose the error you are pasting is coming from IE. I'm not that updated when it comes to recent IE versions, but historically IE has a bad reputation for giving you the right error in the right place. Please try using Firefox with Firebug, or Chrome/Safari with their own debugging extension. They are usually more friendly when it comes to report errors.
In callAjax you are using "name", where is it defined? Where does it comes from? Maybe, as Haim Evgi said, you should make callAjax take two parameters, callAjax(id,name), and then call it with two parameters.
Are id (and eventually name) strings? In that case, you should tell javascript they are string by placing them between single or double quotes, like callAjax('$id1','$newName').
A few unrelated notes about the javascript snipped you posted.
you don't use semi colons at the end of lines, I strongly suggest you to use them. I can remember how tedious it was when years ago I started programming, but after a few weeks it gets easy, and after a couple of years you'll end with a semicolon even the greeting card for your mom birthday. Without semicolons, some (stupid) javascript parsers will fail, and your code will be much harder to minimize.
You're saving the XMLHttpRequest inside a global variable in one function, and then using it in another function. While this does not pose a big risk on this specific snippet, think that you are adding another couple of callAjax functions to call other PHP pages, all sharing that global variable. If the user clicks on a second link before the first one finished its call, upon completion the first one will use the XMLHttpRequest of the second one, and the second too, causing duplicate and wrong pieces of HTML to appear on page.
In GetXmlHttpObject you are declaring a variable called xmlHttp, which is the same name of the global variable. While Javascript will correctly identify this second variable as the one to use in the function instead of the global one, using the same name makes your code harder for humans to understand, and code has to be readable by humans more than from machines to be good code.

simultaneously calling 2 functions via ajax with "onclick"

I have a problem using AJAX. I'm new to this so the answer could be simple!
So, i have this piece of code.
echo '<input type="button" onclick="opinion(1,\''.$v.'\'); op_status(1,\''.$v.'\');"/>';
which is written in php.
The 2 functions that are called via the onclick event, toggle AJAX in 2 different html divs. What i get is the outcome of the second function on both divs.
Any ideas why this could be happening?
Thanks!!
sorry for the inconvenience but this is my first post. so this is one of the 2 (identical, just with different variables) js scripts.
function op_status(op,pid)
{
if (op=="")
{
document.getElementById("opstatus"+pid).innerHTML="";
return;
}
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("opstatus"+pid).innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","post_op_stat_disp.php?ajxpid="+pid,true);
xmlhttp.send();
}
the file that is called makes some checks and outputs a text depending on that checks at a certain html div. the other js script does exactly the same, making some other tests and outputting some other text on another html div. :) however the outputs are the same text echoed in both the divs
First I'd add "var xmlhttp = null;" at the top of your function - that will locally scope the variable instead of making it global in nature - as #David Dorward points out. That would end up assigning the response handler of the ajax request in the second declared function (which ever that happens to be second) as the response handler for both ajax requests and you'd get the behavior you describe.
If you're still getting the same text in both div's then I'd suspect that both javascript functions are calling post_op_stat_disp.php instead of the opinion function calling what I would guess to be post_opinion_disp.php and as a result it is returning the same data to each div. Or (even more unlikely) that both post_opinion_disp and post_op_stat_disp are returning the same result.
Since this problem isn't really germain to AJAX but instead is likely a coding problem - I would suggest navigating manually to http://[server]/post_op_stat_disp.php?ajaxid=test and your other url and see what should be populated in both divs.
Then I would highly suggest that you abstract your ajax code to some common function so that you are not duplicating the http status code and xmlhttp instantiation logic. And though it may not help you solve this particular problem, it would reduce your code size to something along these lines if you followed #Jared Farrish's advice and used jquery:
function op_status(op, pid) {
if (!op) return $('#opstatus' + pid).html("");
$.get('post_op_status_disp.php?ajaxid=' + pid, function(r) {
$('#opstatus' + pid).html(r);
});
}
My money is on the var key word which will ensure you get two different xmlhttp objects instead of one global one.
But as most have already commented - you might want to post the generated results to help us out in helping you track this bugger down.
Thanks, let us know how it turns out!

Fetching file with AJAX, can't read PHP

I have checked the suggestions that came up before posting, hope I didn't miss anything now.
I have a piece of code that I use to get txt-files for my website but now I need to redo the code so it gets both txt and php-files, but it just won't read the php-script. I'm a bit afraid to mess up the code at this moment so I'm walking on the safe side of the road and ask here if anyone knows a good add to the code. It's quite embarrasing that I still have codes for IE 5&6 in it, so if you wish to remove that at the same time, go ahead. I won't hate you for it, I promise.
UPDATE:
I have four files:
html - Calling the .js-file with the ajax-script.
js - With all my javascript(and simular)-codes.
php - That contains... Well, you get the point.
I have to call the php-code somehow, like I call my txt-files, but of course so the php works as it should. I am very new to AJAX, so I don't dare to mess around with this code at the moment, but I figured that I might be able to add some kind of if-statement that calles the php-file as it is intended to be.
But I have no clue what that code might be and where to put it for things to work accordingly. Any help would be appritiated and credited in the code, of course.
Heres the AJAX-code that is contained within the .js-file:
/*Load the link.*/
function loadXMLDoc(url)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("leftCol").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
/*Highly unnecessary, but I wanted to see if it worked and it looks better on the .html-page.*/
function get_link(url)
{
loadXMLDoc(url);
}
As the above commenter said, it is best to use a 3rd party tool for such things - if for no other reason than to greatly increase cross-browser compatibility.
if you were to use jQuery, the code would be reduced to.
function get_link(url)
{
$.ajax({url: url, success: success:function(result){
//the code / resulting string will be in the result variable.
}});
}
jQuery CDN Hosted: http://code.jquery.com/jquery-1.5.min.js
Let me ask this... if you change your code to
function get_link(url)
{
window.location=url;
}
Does your web browser successfully navigate to the page you are trying to retrieve via AJAX? If not, there is likely a problem with your PHP syntax.
it just won't read the php-script
It's a rather vague statement, but here are few pointers that could be the solution :
PHP file are interpreted on the server so when you do an Ajax call to that page what you receive on the client side is the result of that php script, not his content.
You are assigning the result of the query directly in the HTML, if the result contains data that does not render anything, you won't see anything. For example the content <script>Text here bla bla bla</script> will just show nothing.
If you want to make sure you get some data back from a file, you can just alert the content when you receive it.
Make sure your path to your PHP page is correct. To detect if the file is not giving a 404 error code or any other error code, you can use this :
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
document.getElementById("leftCol").innerHTML = xmlhttp.responseText;
} else {
alert("Error " + xmlhttp.status);
}
}
}

Categories