Returning AJAX responseText from a seperate file - php

This question may have been asked a million times in the past but I am yet to come across a solution. So I ask again, hoping a less
aggressive answer like "Look somewhere else" or "Don't repeat
questions". If the reader feels the urge to type any of or similar to
the aforementioned sentences, I can only request the reader to refrain
from doing so and ignore this post completely. Any help is greatly
appreciated.
The problem
In my program, an AJAX script works to communicate with a PHP script. There are no syntax errors. The AJAX receives the responseText well and alerts it out.
alert(request.responseText); //this works as desired
But fails to return it to another function.
return(request.responseText); //this actually returns undefined
The full code
Client file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>test</title>
<script type="text/javascript" language="javascript" src="ajax.js"></script>
<script type="text/javascript" language="javascript">
function createXMLHttp()
{
var xmlHttp = null;
if(window.XMLHttpRequest)
{
xmlHttp = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlHttp;
}
function ajax_phprequest(data, php_file)
{
var request = createXMLHttp();
request.open("POST", php_file, true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send(data);
request.onreadystatechange = function()
{
if (request.readyState == 4)
{
document.write(request.responseText);
return request.responseText; //changed from return(request.responseText;);
}
}
}
function foo()
{
alert(ajax_phprequest("user=defuser&pass=123456","auth.php"));
}
</script>
</head>
<input type="button" id="somebutton" value="Call foo()" onclick="foo();" />
<body>
</body>
</html>
The full code
auth.php file
<?php
$user;
$pass;
if (isset($_POST['user'])) $user = $_POST['user'];
else
{
echo 'err_u_Username is not specified';
exit();
}
if (isset($_POST['pass'])) $pass = $_POST['pass'];
else
{
echo 'err_p_Password is not specified';
exit();
}
if ($user = 'defuser' && $pass = '123456') echo ('That\'s right!');
else echo ('That\'s not right!');
?>
This can easily be solved by including the code in the same file as the document. But I wish to call the function from a different file and then return it to the file that has foo() or the document. Simply, I want the AJAX function to return the responseText without it giving an `undefined' every time. If this has anything to do with synchronization: I want to know of any workarounds against this problem.

The gist of it has already been mentioned, but I would like to go into a bit more depth as to why this doesn't work.
You have the following code:
request.onreadystatechange = function()
{
if (request.readyState == 4)
{
document.write(request.responseText);
return(request.responseText);
}
}
Basically, you are setting the onreadystatechange event to the value of an anonymous function. In that anonymous function, you are returning a value, which won't be returned to the caller of ajax_phprequest(), but to the caller of the anonymous function, which is the event system and which doesn't care much about what value is returned.
This happens this way because it all happens asynchronously. In other words, you call ajax_phprequest() and all that happens at that moment happens behind the screens. The user can continue working like nothing has happened. However, in the background, the php file is requested and hopefully returned. When that happens, you get to use the contents, but the moment at which you called ajax_phprequest() has long since passed.
A proper way would be to use a callback function instead. It could look something like this:
function ajax_phprequest(data, php_file, callback)
{
var request = createXMLHttp();
request.open("POST", php_file, true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send(data);
request.onreadystatechange = function()
{
if (request.readyState == 4)
{
document.write(request.responseText);
callback(request.responseText);
}
}
}
function foo()
{
ajax_phprequest("user=defuser&pass=123456","auth.php", function (text)
{
alert(text);
});
}

That is because the call is ASYNCHRONOUS so you cannot return from stack the usual way, i.e. your alert(ajax_phprequest("user=defuser&pass=123456","auth.php")); is evaluated before the ajax response is returned ... you need to use a callback:
function callback( text ){
// something
}
...
if (request.readyState == 4){
callback( request.responseText );
}

Related

PHP sends answer twice

I have some experience with Nodejs so I wanted to try some php too.
I want to make a GET request in a php file and get a response. While I get data, I receive them twice. I cheked the network tab on my browser and I see only one request. The html/javascript code works without a problem on nodejs, php persists on sending data twice. Why does this happen?
Html file:
<html>
<head>
<title>Hello World</title>
</head>
<body>
<p>Hello User!!</p>
<button id="button">Get Request</button>
</body>
<script>
document.getElementById("button").onclick = function () {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "test.php?id=HI", true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 || this.status === 200) {
console.log(this.responseText);
}
};
xmlhttp.send();
};
</script>
</html>
test.php file:
<?php
ini_set('display_errors', 1);
$id = $_GET["id"];
if($id == "HI"){
echo ("Noice!");
}else {
echo ("I am sowwy :3");
}
?>
Disclaimer: "I understand this code does nothing important and always sends the same response. It is just an experiment to get myself familiar with php".
Thanks for your time.
You are not sending the responset twice but logging it twice.
onreadystatechange should be:
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4) {
if (this.status === 200) console.log(this.responseText);
}
};

Ajax submit to self PHP file, but seems the PHP function do not execute

Ajax submit to self PHP file, but seems the PHP function do not execute.
<?php
function request(){
echo "<h1>requested</h1>";
}
?>
<html id="html">
<button id="btn_click" onclick="request1()">click</button>
</html>
<script type="text/javascript">
function request1(){
document.write("<h1>been clicked</h1>");
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "/index.php", true);
xmlhttp.send();
}
</script>
The JavaScript execute success, but seems the PHP code did not execute.
To add to what gibberish said, however, there's more to it. You must also keep in mind you don't seem to be executing the function at all.
A PHP function does nothing unless it is called.
function request() {
echo "<h1>Hello</h1>"
}
The function above will not be affected unless you call it:
request() // <h1>Hello</h1>
Also AJAX is best used when keeping requests simple. You send a request /path/to/file.php then that requests should return a plain text response or a JSON object, or a fully rendered static page if you are using a modal or some static item on your site.
/path/to/file.php
<?php
if( $_GET['clicked'] ) {
// do whatever
echo json_encode([
'user_id' => 1,
'total_clicks' => $_GET['clicked'],
'random_number' => rand(100, 999)
]);
}
The JS can easily handle the response:
function request(id) {
return fetch(`/path/to/file.php?clicked=${id}`)
.then(res => {
console.log(res);
body.innerHTML += res.user_id;
body.innerHTML += res.total_clicks;
})
.catch(err => console.error(err));
}
This will be the simplest way to have your server return information from the DB and make your page content as interactive as you need it to be,.
$_SERVER['HTTP_X_REQUESTED_WITH'] help us to detect an AJAX request
<?php
//Check Here Ajax Request
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){
function request(){
echo "<h1>requested</h1>";
}
request();
die;
}
?>
<html id="html">
<body>
<button id="btn_click" onclick="request1()">click</button>
<div class="response" id="result" ></div>
<script type="text/javascript">
function request1(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) { // XMLHttpRequest.DONE == 4
if (xmlhttp.status == 200) {
document.getElementById("result").innerHTML = xmlhttp.responseText;
}
}
};
xmlhttp.open("GET", "./index.php", true);
xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); // <-- ADD this
xmlhttp.send();
}
</script>
</body>
</html>

Request ready state always returns 0?

I am new to JavaScript and trying to play with some Ajax to dynamically load HTML into a <div> element. I have a PHP page that spits out a JSON with the HTML needed to insert into the <div>. I have been testing and cannot get the call to work. I started to do alerts on my readystate, and I get 0 and then nothing else. From my understanding, the function sendData() should be called every time the readystate changes, but it appears to only do it once, or the readystate never changes, so it only gets called once...?
This is my PHP
<?php
$array['html'] = '<p>hello, menu here</p>';
header('Content-type: application/json');
echo json_encode($array);
?>
This is my HTML
<!DOCTYPE html>
<html>
<head>
<title>Veolia Water - Solutions and Technologies Dashboard</title>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<meta name="description" content="Veolia Water - Dashboard"/>
<meta http-equiv="imagetoolbar" content="no" />
<meta author="Nathan Sizemore"/>
<link rel="stylesheet" href="./css/stylo.css" media="screen"/>
</head>
<body>
<div id="menu">
</div>
<div id="content">
</div>
</body>
<script src="./js/dashboard.js"></script>
</html>
This is my JavaScript
var request;
window.onload = function()
{
load_menu();
}
//Load menu function
function load_menu()
{
request = getHTTPObject();
alert(request.readyState);
request.onreadystatechange = sendData();
request.open("GET", "./php/menu.php", true);
request.send(null);
}
function getHTTPObject()
{
var xhr = false;
if (window.XMLHttpRequest)
{
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
try
{
xhr = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
xhr = false;
}
}
}
return xhr;
}
function sendData()
{
alert(request.readyState);
// if request object received response
if (request.readyState == 4)
{
var json = JSON.parse(request.responseText);
document.getElementById('menu').innerHTML = json.html;
alert(json.html);
}
}
Thanks in advance for any help!
Nathan
Use this:
request.onreadystatechange = sendData;
Note that the () are removed from sendData()
What you had before was immediately executing sendData and returning its result to onreadystatechange. Since nothing is actually returned, the value is undefined. It wasn't actually setting anything to onreadystatechange and therefore not actually executing anything when the state changes. The onreadystatechange property expects a reference to a function...which is exactly what sendData is.
In your code, since sendData was executed once (accidentally), the state reported is 0 (the XHR's initial state).
Change this line
request.onreadystatechange = sendData();
To this
request.onreadystatechange = sendData;
The first code calls sendData and assigns the result as the handler.
The second one assigns the function itself.
request.onreadystatechange = sendData();
should be
request.onreadystatechange = sendData;
You're calling sendData immediately and using the result of that function as the listener, rather than using the function itself.

Refreshing my php page with AJAX every 5 seconds

I'm creating a link-sharing website and on my index.php page (the page I want to refresh every 5 seconds) there are posts/links that must appear automatically (AJAX refreshing) without the user to refresh by him/herself or pressing F5 the whole time.
How would this work, precisely?
You should use the setInterval javascript function to deal with this issue.
setInterval(callServer, REFRESH_PERIOD_MILLIS);
See:
some info on ajax Periodic Refresh
javascript setInterval documentation
[edit] some good refresh examples, especially without js framework (depending wether you want to use jquery, mototools, another or no framework...)
you have to user the setInterval method to call your ajax function to inject new content into your div:
<HTML>
<HEAD>
<TITLE>Hello World Page</TITLE>
<script language="JavaScript">
function xmlhttpPost(strURL) {
var xmlHttpReq = false;
// Mozilla/Safari
if (window.XMLHttpRequest) {
xmlHttpReq = new XMLHttpRequest();
if (xmlHttpReq.overrideMimeType) {
xmlHttpReq.overrideMimeType('text/xml');
// See note below about this line
}
// IE
} else if (window.ActiveXObject) { // IE
try {
xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!xmlHttpReq) {
alert('ERROR AJAX:( Cannot create an XMLHTTP instance');
return false;
}
xmlHttpReq.open('GET', strURL, true);
xmlHttpReq.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');
xmlHttpReq.onreadystatechange = function() {
callBackFunction(xmlHttpReq);
};
xmlHttpReq.send("");
}
function callBackFunction(http_request) {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
var responceString = http_request.responseText;
//TODO implement your function e.g.
document.getElementById("myDiv").InnerHTML+ = (responceString);
} else {
alert('ERROR: AJAX request status = ' + http_request.status);
}
}
}
setInterval("xmlhttpPost('test.php')", 5000);
</script>
</HEAD>
<BODY>
Hello World
<div id="myDiv"></div>
</BODY>
</HTML>
Is there a need to use AJAX?
Unless I'm missing something; you could use the meta refresh tag:
<meta http-equiv="refresh" content="5">
I would recommend increasing the time between refreshes as this will put a heavier load on the server and may cause to freeze, or slow down the site.
Use setInterval(myAjaxCallbackfunction,[time in ms]).
Callback uses property of js that function are first class members(can be assigned to variables), and can be passed as argument to function for later use.

How to call multiple AJAX functions (to PHP) without repeating code

I have a little script which uses AJAX and PHP to display an image. You can see below that if I call the function mom() it looks in the PHP file index.php?i=mom and displays the image I'm looking for.
But I need the javascript to be lighter as I have 30 images and for each one I have to modify and copy the script below. Is there not a simpler way to have the functions be different and still call a different page?
<script type="text/javascript">
function mom()
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
HandleResponse(xmlHttp.responseText);
}
}
xmlHttp.open("GET", "index.php?i=mom", true);
xmlHttp.send(null);
}
function HandleResponse(response)
{
document.getElementById('mom').innerHTML = response;
}
</script>
My Trigger is this
<a href="#" onclick='mom();' />Mom</a>
<div id='mom'></div>
You could modify your function so it takes a parameter :
// The function receives the value it should pass to the server
function my_func(param)
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
// Pass the received value to the handler
HandleResponse(param, xmlHttp.responseText);
}
}
// Send to the server the value that was passed as a parameter
xmlHttp.open("GET", "index.php?i=" + param, true);
xmlHttp.send(null);
}
And, of course, use that parameter in the second function :
function HandleResponse(param, response)
{
// The handler gets the param too -- and, so, knows where to inject the response
document.getElementById(param).innerHTML = response;
}
And modify your HTML so the function is called with the right parameter :
<!-- for this first call, you'll want the function to work on 'mom' -->
<a href="#" onclick="my_func('mom');" />Mom</a>
<div id='mom'></div>
<!-- for this secondcall, you'll want the function to work on 'blah' -->
<a href="#" onclick="my_func('blah');" />Blah</a>
<div id='blah'></div>
This should work (if I understand correctly)
<script type="text/javascript">
function func(imgName)
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
document.getElementById(imgName).innerHTML =
}
}
xmlHttp.open("GET", "index.php?i=mom", true);
xmlHttp.send(null);
}
</script>
MARTIN's solution will work perfectly.
By the way you should use some javascript framework for Ajax handling like jQuery.
It will make your life easy.
If you are having light weight images you preload the images on your page.
I solved this by making an array of in your case xmlHttp and a global variable, so it increments for each request. Then if you repeatedly make calls to the same thing (eg it returns online users, or, whatever) then you can actually resubmit using the same element of the array too.
Added example code:
To convert it to a reoccuring event, make a copy of these 2, and in the got data call, just resubmit using reget
var req_fifo=Array();
var eleID=Array();
var i=0;
function GetAsyncData(myid,url) {
eleID[i]=myid;
if (window.XMLHttpRequest)
{
req_fifo[i] = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
req_fifo[i] = new ActiveXObject("Microsoft.XMLHTTP");
}
req_fifo[i].abort();
req_fifo[i].onreadystatechange = function(index){ return function() { GotAsyncData(index); }; }(i);
req_fifo[i].open("GET", url, true);
req_fifo[i].send(null);
i++;
}
function GotAsyncData(id) {
if (req_fifo[id].readyState != 4 || req_fifo[id].status != 200) {
return;
}
document.getElementById(eleID[id]).innerHTML=
req_fifo[id].responseText;
req_fifo[id]=null;
eleID[id]=null;
return;
}
function reget(id) {
myid=eleID[id];
url=urlID[id];
req_fifo[id].abort();
req_fifo[id].onreadystatechange = function(index){ return function() { GotAsyncData(index); }; }(id);
req_fifo[id].open("GET", url, true);
req_fifo[id].send(null);
}
The suggestions to parameterize your function are correct and would allow you to avoid repeating code.
the jQuery library is also worth considering. http://jquery.com
If you use jQuery, each ajax call would literally be this easy.
$('#mom').load('/index.php?i=mom');
And you could wrap it up as follows if you'd like, since you say you'll be using it many times (and that you want it done when a link is clicked)
function doAjax(imgForAjax) { $('#'+imgForAjax).load('/index.php&i='+imgForAjax);}
doAjax('mom');
It makes the oft-repeated ajax patterns much simpler, and handles the issues between different browsers just as I presume your getXMLhttp function does.
At the website I linked above you can download the library's single 29kb file so you can use it on your pages with a simple <script src='jquery.min.js'></script> There is also a lot of great documentaiton. jQuery is pretty popular and you'll see it has a lot of questions and stuff on SO. ajax is just one of many things that jQuery library/framework (idk the preferred term) can help with.

Categories