I am quite a noob to AJAX Requesting and PHP and I got a question:
I am trying to do a GET request to a php file on my wamp server but it's responseText stays blank and when I check the status code when the readyState is 4, it's 0.
When I execute the php file in the browser it returns my expectation: An array with JSON Objects.
Does anyone know the answer?
Javascript code:
this.getCars = function(id) {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
}
else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
var that = this;
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4)
{
alert(xmlhttp.status);
//that.lastTableCars = JSON.parse(xmlhttp.responseText);
}
}
xmlhttp.open("GET","http://localhost/getCars.php?q="+id,true);
xmlhttp.send(null);
}
PHP:
<?php
$q=$_GET["q"];
$con = mysql_connect('127.0.0.1', 'root', 'root');
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("autobay", $con);
$sql= "SELECT * FROM autoos WHERE id = '".$q."'";
$result = mysql_query($sql);
$info = [];
while( $row = mysql_fetch_assoc( $result)){
$info[] = $row;
}
echo json_encode($info);
mysql_free_result($result);
mysql_close();
For one, use jQuery to help troubleshoot. It's going to make your life so much easier. Even if you end up wanting to use raw xmlhttprequest, I'd suggest bringing jQuery in to rule out xmlhttprequest problems in your code, and more quickly hone in on the real issue.
Translation: I'm not comfortable with raw xmlhttprequest, so in order to help you let's switch to jQuery. You can go back when the issue is resolved! =)
this.getCars = function(id) {
$.get("/getCars.php?q="+id, function(data) {
alert("response from server: " + data);
});
}
http://api.jquery.com/jQuery.get/
Also make sure you are using Chrome Dev Tools or Firebug to inspect the response from your server, it's possible that it's failing there.
Update:
Make sure your HTML page (that is making the ajax call) and the PHP script are running on the same domain (localhost). I noticed you were specifying the full http://localhost URL in your ajax call. Ajax does not work cross-domain (though there are workarounds, look at JSONP if you really need to do this cross-domain). Best bet is to get your HTML page loading from the same domain as the PHP script.
Update 2:
Actual issue was that the OP was loading the HTML from a folder on his computer (not via http://localhost) and trying to make an ajax call to http://localhost. The ajax call was failing since this is technically cross domain.
Related
I just started this book - "AJAX and PHP Second edition" and I failed on the very first example.I'm pretty sure the code is just as it is shown in the book, but still when I run index.htm in the error console(Mozzila 6.0) I get this : "xmlResponse is NULL http://localhost/ajax/quickstart/quickstart.js.I don't know what's going on but really don't want to give up at the very begining so I'll pase all the 3 files and hopefully anyone would point me where the problem is.
Here is the index.htm :
<!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>
<title>AJAX with PHP, 2nd Edition: Quickstart</title>
<script type="text/javascript" src="quickstart.js"></script>
</head>
<body onload="process();">
Server wants to know your name:
<input type="text" id="myName" />
<div id="divMessage" ></div>
</body>
</html>
here is the quickstart.js :
// stores the reference to the XMLHttpRequest object
var xmlHttp = createXmlHttpRequestObject();
// retrieves the XMLHttpRequest object
function createXmlHttpRequestObject()
{
// stores the reference to the XMLHttpRequest object
var xmlHttp;
// if running Internet Explorer 6 or older
if(window.ActiveXObject)
{
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
xmlHttp = false;
}
}
// if running Mozilla or other browsers
else
{
try {
xmlHttp = new XMLHttpRequest();
}
catch (e) {
xmlHttp = false;
}
}
// return the created object or display an error message
if (!xmlHttp)
alert("Error creating the XMLHttpRequest object.");
else
return xmlHttp;
}
// make asynchronous HTTP request using the XMLHttpRequest object
function process(name)
{
// proceed only if the xmlHttp object isn't busy
if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0)
{
// retrieve the name typed by the user on the form
name = encodeURIComponent(
document.getElementById("myName").value);
// execute the quickstart.php page from the server
xmlHttp.open("GET", "quickstart.php?name=" + name, true);
// define the method to handle server responses
xmlHttp.onreadystatechange = handleServerResponse;
// make the server request
xmlHttp.send();
}
else
// if the connection is busy, try again after one second
setTimeout('process()', 1000);
}
// callback function executed when a message is received from the
//server
function handleServerResponse()
{
// move forward only if the transaction has completed
if (xmlHttp.readyState == 4)
{
// status of 200 indicates the transaction completed
//successfully
if (xmlHttp.status == 200)
{
// extract the XML retrieved from the server
xmlResponse = xmlHttp.responseXML;
// obtain the document element (the root element) of the XML
//structure
xmlDocumentElement = xmlResponse.documentElement;
// get the text message, which is in the first child of
// the the document element
helloMessage = xmlDocumentElement.firstChild.data;
// display the data received from the server
document.getElementById("divMessage").innerHTML =
'<i>' + helloMessage
+ '</i>';
// restart sequence
setTimeout('process()', 1000);
}
// a HTTP status different than 200 signals an error
else
{
alert("There was a problem accessing the server: " +
xmlHttp.statusText);
}
}
}
and finally the quickstart.php :
<?php
// we'll generate XML output
header('Content-Type: text/xml');
// generate XML header
echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
// create the <response> element
echo '<response>';
// retrieve the user name
$name = $_GET['name'];
// generate output depending on the user name received from client
$userNames = array('YODA', 'AUDRA', 'BOGDAN', 'CRISTIAN');
if (in_array(strtoupper($name), $userNames))
echo 'Hello, master ' . htmlentities($name) . '!';
else if (trim($name) == '')
echo 'Stranger, please tell me your name!';
else
echo htmlentities($name) . ', I don\'t know you!';
// close the <response> element
echo '</response>';
?>
Thanks in advanced!
Leron
There are a couple of problems I found with your code. Mentioning some of them
You are calling the process() on body-onload. This means, when the DOM is ready, the browser calls the process() function. This, IMO, is not something you would want. Instead, have a button, which calls this process function with the onclick event. Something like:
<button onclick="process('YODA');return false;">Click Me!</button>
Process is defined as taking one parameter called name, you are passing none. So, make a fix something like this:
<button onclick="myProcess();return false;">Click Me!</button>
And is your JS section/file
function myProcess(){
process(encodeURIComponent(document.getElementById('myName').value));
}
Do not have that document.getElementById(..) inside the process function. It defeats the entire purpose of passing that parameter 'name'
I would ask you to use a really good browser like Mozilla Firefox, or Google Chrome (since you seem to give IE6 a prefence in your code, atleast seems like it!). Chrome has a fantastic inspector window. Once you get the hang of it, you will almost fall in love with it. I did! ;-)
I would suggest, you use libraries like jQuery(www.jquery.com) or something, for ajax. Makes your life easier! :-)
EDIT
I would suggest the following steps, since you want to get this piece of code working.
First open the url [BASE-URL]/quickstate.php?name=YODA. If everything is just fine, you should see the XML that should be the response to your AJAX call. If not, there's some problem with the PHP file(or a few settings of your server), and not anything else. I feel this step wouldn't be a problem.
Next, once the page is loaded, type 'YODA' in the textbox, type this in the browser's URL box: javascript:process(''). This should call the function that has the ajax call. You could keep a tab on the data transferred section of the firebug(I dont know the name exactly, but its the 'Network' section in Google Chrome). You could analyse the headers sent to the PHP scripts, and the response (including the HTTP error codes) sent back to you from the server. I also feel this wont be a problem.
What causes the problem is: The DOM of the page is loaded. The AJAX call is made once the DOM is ready. This means the AJAX request is made even before you type anything in that textbox. And thus, the request that goes to the server has a empty value for name parameter. This is exactly, (IMO) the reason why things are not working for you. But even then, this is not the reason why you see a null for XML out there. Could you do a console.log(xmlHttp) and tell us the results?
That all looks correct. Where are hosting the PHP script? On a local installation of Apache, or a server you have access to? In Firefox, you can install the incredible Firebug add-on, go to the scripts tab, and see exactly what the request is returning. Whatever it is, Fx isn't recognising it as XML (hence the xmlResponse member being NULL).
I am writing this javascript that will be used on several other domains which calls a php script(only on my domain) to return an array. I am using xmlhttp and it works great when testing on my domain, but as soon as the javascript is placed or called from a separate domain it completely breaks. Anybody know how to make this request cross-domain?
Note: I had to perform a weird little hack to allow me to make two separate calls and make sure that they were both returned before processing. Anyways this does work perfectly every time on my domain.
This is tin the javascript file that calls my php code for the array
function getUrls(){
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
xmlhttp2 = new XMLHttpRequest();
}
else {
// code for IE5 and IE6
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
// code for IE5 and IE6
xmlhttp2 = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
parsedJSONurls = JSON.parse(xmlhttp.responseText);
xmlhttp2.open("GET", "http://mydomain.com/connect.php?q=companies", true);
xmlhttp2.send();
}
}
xmlhttp2.onreadystatechange = function(){
if (xmlhttp2.readyState == 4 && xmlhttp2.status == 200) {
parsedJSONcompanies = JSON.parse(xmlhttp2.responseText);
runLoop(parsedJSONurls, parsedJSONcompanies);
}
}
xmlhttp.open("GET", "http://mydomain.com/connect.php?q=urls", true);
xmlhttp.send();
}
Try adding this header to your connect.php file
header('Access-Control-Allow-Origin: http://domain1.com, http://domain2.com');
If you want to permit all domains instead of a whitelist
header('Access-Control-Allow-Origin: *');
https://developer.mozilla.org/en/http_access_control
The reason for this is the same origin policy. It was put in place to stop malicious scripts from accessing sensitive data from other websites. You should look into writing a JSONP request as a workaround for your problem.
There's an ongoing community wiki I started last year that explains many ways of circumventing the same origin policy. A solution that fits your situation can most likely be found there.
Same with others, it's caused by same origin policy.
Suppose page is at "a.com", no matter where JavaScript file is,
As long as you use XMLHttpRequest approach, you can only access data from a.com.
Even subdomain a.a.com can't access a.com.
You can have 2 options:
1) Use <script/> tag hack
JSONP is great, but it seems you don't rely on any library.
It's a JavaScript nature you can include JavaScript locating on other domain. <script/> tag hack is a simple technique which dynamically create and append <script/> node.
And its src attribute is the URL which is in different domain.
function getUrl(url) {
var scriptEl = document.createElement("script");
scriptEl.src = url;
scriptEl.async = true;
document.getElementsByTagName("head")[0].appendChild(scriptEl);
}
// Predefined callbacks
window.companyCallback = function (responseData) {
parsedJSONCompanies = responseData;
};
window.urlCallback = function (responseData) {
parseJSONurls = responseData;
};
getUrl("http://mydomain.com/connect.php?q=companies");
getUrl("http://mydomain.com/connect.php?q=urls");
Of course you also have to modify your PHP to meet the need.
<?php
header("content-type: application/json");
if ($_GET['q'] === "urls")
{
echo "companyCallback(";
json_encode($result);
echo ");";
}
else
{
echo "urlCallback(";
json_encode($result);
echo ");";
}
?>
2) Place proxy.php in different domain
The above method is what I recommended.
If you don't want to revamp your code heavily, use proxy technique instead.
You must have privilege to add a proxy.php on different hosts.
The content like this:
<?php
$url = "http://mydomain.com/connect.php?q=" . $_GET["q"];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
echo $result;
?>
NOTE: Be careful about security issue, you need to check where the request from.
In JavaScript, you just need to point the url in xmlhttp.open() to this same domain PHP.
xmlhttp.open("proxy.php?q=urls", true);
Hope it helps.
Like others said you could use JSON-p) for that or if the browsers supports(new A-graded browsers do) CORS you could use that instead.
As mentioned most non html5 dont allow cross browser ajax requests. To get around this I call a remote javascript script.
use javascript to add a line like
<script type="text/javascript" src="http://www.somemedomain.xxx/myjavascript.php?arg1=xxx&arg">
on the myjavascript.php file on the other server, you can process, collect information collected from the browser.
you have to encode the php file as javascript.
header( "content-type: application/javascript" ) //check php.net
This will work in ie6+
I have a problem with Ajax. I'm totally noob with Ajax, and I apologize for such a stupid question.
I have a list of elements (loaded by a db) that I want to manage, i.e. Remove, Modify their name..; I want to use ajax to change db and the list.
But I want that the page is modified only AFTER the db has been modified. I can modify the page before the db is modified but it's not what I want.
That's my code:
function setXMLHttpRequest() {
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
return xhr;
}
function modifyCat(n,newN){
xhrObj = setXMLHttpRequest();
var url = "modifyCat.php?action=modify&cat="+n+"&newCat="+newN;
xhrObj.open("GET", url, true);
links = document.getElementById("cat").getElementsByTagName("a");
updatePage(links);
xhrObj.send(null);
}
function updatePage(links) {
if (xhrObj.readyState == 4) {
var risp = xhrObj.responseText;
//code that works... if not put inside this if!
}
xhrObj.send(null);
}
ModifyCat.php is
//...
else if($action='modify'){
$n = cleanSimpleString($_GET['cat']);
$nN = cleanSimpleString($_GET['newCat']);
$qry = "UPDATE Categorie Set Nome='$nN' WHERE Nome='$n'";
$check = mysql_query($qry) or $db=0;
}
As I understand if (xhrObj.readyState == 4) should do want I'm asking. Instead with that If nothing happens (in the page, the php is correctly loaded). Without that If the page is correctly reloaded but while the db is working..
edit.
I would like to do that without framework, I think it's a simple thing that can be solved simply.
Thank you.
If you're "totally noob with Ajax" I'd recommend using an Ajax library, such as jQuery. Have a look at their Ajax page and you'll see that it's much more straightforward than working directly with XHR objects.
Also, you've got a typo - you've use hrObj in modifyCat.
You can either use the XMLHttpRequest to do a synchronous or asynchronous request. A synchronous request is easier to program, but will block your page until the result becomes available. An asynchronous request will execute a callback function when the result has become available. There are a number of events for which the callback will be executed, readyState = 4 means the result is available, see also:
http://en.wikipedia.org/wiki/XMLHttpRequest#The_onreadystatechange_event_listener
(and of course the rest of that article)
Having said that, take the suggestions elsewhere to heart, it is much easier (and more cross-browser compatible) to use jquery (or similar javascript/ajax library) to do this stuff.
It would save you a lot of headache if you just used jquery - it can be as easy as doing this:
$.get("modifyCat.php", { action: "modify", cat: n, newCat: newN },
function(data){
alert("Data Loaded: " + data);
});
http://api.jquery.com/jQuery.get/
I have another question. XMLhttpRequests haunt me. Everything is now in the database but I need this data to update my page on firt page load or reload. The XHR is triggered in JavaScript file which triggers PHP-Script. PHP-Script access MySQL database. But how do I get the fetched records back into my JavaScript for page update. I can not figure it out.
First my synchronous XMLhttpRequest:
function retrieveRowsDB()
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","retrieveRowData.php", false);
xmlhttp.send(null);
return xmlhttp.responseText;
}
Then my PHP-Script:
<?php
$con = mysql_connect("localhost","root","*************");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("sadb", $con);
$data="SELECT * FROM users ORDER BY rowdata ASC";
if (!mysql_query($data,$con))
{
die('Error: ' . mysql_error());
}
else
{
$dbrecords = mysql_query($data,$con);
}
$rowdata = mysql_fetch_array($dbrecords);
return $rowdata;
mysql_close($con);
?>
What am I missing here? Anyone got a clue?
PHP scripts don't return to JavaScript. You have to echo the data (encoded in some way, for example json_encode).
Really, if you're doing any kind of ajax, you'll make your life a lot easier by using an ajax library.
There's not much technically wrong with your code so far - you just need to actually do something with it.
In your PHP file, instead of return $rowdata;, you need to output it in some way. Currently, it's just sending a blank document back to the javascript, so you'll need to echo out the code. Normally, when using a number of objects to be returned to javascript, JSON is a good format. Check out json_encode.
On the other side, in the js, you'll need to take the response and update the page in some manner. Currently, you're just returning it again.
I suggest you go through a few ajax tutorials, and consider using a framework such as jQuery to do the heavy lifting for you. You might also want to do a bit of reading on this topic, as you have some fundamental misconceptions.
The problem is xmlhttp.responseText, it doesn't exist at the time, try adding this just before your return statement:
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
doSomething(xmlhttp.responseText);
}
}
}
Basically you have to wait until the data is available, it takes time to make an HTTP request and get a response.
I am creating a web game for learning new words aimed at children.
I have a set of four links each displaying a specific word retrieved from my database and a clue, I need to check that the word which has been selected matches the correct word for that clue.
I know that I need to use javascript because of the onClick function and I can successfully check whether the word selected matches the correct word. However, I then need to update a score held in the database if the word is matched correctly, therefore I would need to use php.
From what I can gather this means I must use AJAX but I can't find a good example of anyone using AJAX onClick of a link to then update a database.
I have attempted to do this...but its probably completely wrong as I couldn't get it to work properly:
//This is my link that I need to use in my game.php file where $newarray[0] is that answer I want to check against $newarray[$rand_keys]
<a onClick=originalUpdateScore('$newarray[0]','$newarray[$rand_keys]')>$newarray[0]</a>
//my attempt at ajax in a score.js file
var xmlHttp;
function originalUpdateScore(obj,corr){
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
alert ("Browser does not support HTTP Request");
return;
}
if(corr == obj){
var url="getscore.php";
//url=url+"?q="+str;
//url=url+"&sid="+Math.random();
xmlHttp.onreadystatechange=stateChanged;
//xmlHttp.open("GET",url,true);
xmlHttp.open(url,true);
xmlHttp.send(null);
alert('Correct');
}
else
{
alert('AHHHHH!!!');
}
window.location.reload(true);
}
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;
}
//attempting to update the database in a getscore.php file
<?php
//$q=$_GET["q"];
include("dbstuff.inc");
$con = mysqli_connect($host, $user, $passwd, $dbname)
or die ("Query died: connection");
$sql= "UPDATE `temp` SET `tempScore`= `tempScore`+1 WHERE (temp.Username='$_SESSION[logname]')";
$showsql = "SELECT `tempScore` FROM `temp` WHERE (temp.Username='$_SESSION[logname]')";
$result = mysqli_query($con, $showsql);
echo "$result";
mysqli_close($con);
?>
I would highly recommend learning AJAX properly - it won't take you ages but will help you understand what you can and can't do with it.
Updating a DB from a web page via AJAX is very common. I would suggest simplifying your JavaScript development using jQuery (a JavaScript library). There is a good introduction to jQuery and AJAX here.
Basically what jQuery will do is write a lot of the boilerplate code for you. What you will end up writing is something like this:
function updateScore(answer, correct) {
if (answer == correct) {
$.post('updatescore.php');
}
}
...
<a onclick="updateScore(this, correct)" ...> </a>
What you're doing here is sending a POST request to updatescore.php when the answer is correct.
Then, in your updatescore.php, you just need to have PHP code like you already do which will update the score in the database.
You can obviously do many more complicate things than this, but hopefully that will be enough to get you started.
I noticed you have "window.location.reload(true);" in your code. Why? That seems like it would make things not work.
You should try to analyze your program to find out where the problem is happening. Then you will be able to ask us a very specific question like "why does Firefox not fire the onClick handler when I click on this link" instead of just posting three pages of code. When you paste so much code, it's pretty hard for us to find your bug.
So here are the questions you should ask:
Is my HTML being parsed correctly? To me, it looks like it might not be parsed correctly because you did not put quotes around the value of onClick. You should use quotes, like: onClick="..." To find out if your HTML is being parsed nicely, you can use Firefox's View->Source feature and look at the colors it prints.
Is my onClick handler getting called? It looks like you are using alert()'s effectively so that's good.
Does the request actually get sent to my server? To determine this, you should use Firefox, and install the Firebug extension. In the "Net" panel, it will show you all the AJAX requests that are being made by your page, and it will show you the results that were returned from the server.
Is the script on my server doing the right thing? So on the server side, you can now add lines like "echo 'hello world';" and you will see that output in the Firebug Net panel, which will help you debug the behavior of your server-side script.
Is my stateChanged function getting called? Once again, use alert() statements, or write to Firebug's debug console.
Once you've narrowed your problem down, try to reduce your code to the simplest possible code that still fails. Then show us the code and tell us exactly what the symptoms of the error are.
On another note, I recommend getting this book: Javascript: The Deinitive Guide, 5th Edition by O'Reilly. It covers lots of cool stuff like AJAX and closures. It costs $50 but it's definitely a good investment because it explains things in a much more coherent way then you'll ever get from free websites.