AJAX 会话调用了两次。第二次不显示警报
AJAX Session called twice. It doesn't show an alert the second time
我有一个 AJAX 会话,它在页面加载时调用一次,在单击后再次调用。第二次它没有获得就绪状态更改,所以我决定通过在函数中放置一个警告框来测试它。警告框显示在页面加载上。但是在点击时它没有显示 - 得到这个 - 即使 PHP 端执行。更令人费解的是,如果我尝试测量就绪状态,它永远不会出现(不是 0、1、2、3 或 4 - 警告框甚至不会出现),而且我没有得到 return 文本.
我最终想要实现的是 xmlhttp.responseText 到 return 的值,就像它在页面加载时所做的那样。我错过了什么?
JavaScript:
function ajaxSession()
{
alert();
xmlhttp = undefined;
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)
{
z = xmlhttp.responseText;
}
}
}
function stateCheck()
{
ajaxSession();
xmlhttp.open('POST', thisurl + '/favoritecheck.php',false);
xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttp.send("0=" + perform + "&1=" + thisplace + ",&2=" + thisusername);
}
function firstCheck()
{
perform = 0;
stateCheck();
if (z == 'found')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-on.png";
document.getElementById("favtext").innerHTML="This is a favorite!";
}
if ( z == 'nouser')
{
perform = 1;
stateCheck();
}
}
function heartCheck()
{
perform = 2;
stateCheck();
if (z == 'added')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-on.png";
document.getElementById("favtext").innerHTML="This is a favorite!";
}
if (z == 'subtracted')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-off.png";
document.getElementById("favtext").innerHTML="Add to your favorites.";
}
}
if (loggedin == 1)
{
document.writeln('<img id="favorite" style="cursor: pointer;" onclick="heartCheck()" src="http://www.********.com/images/favorite-off.png" alt="Favorite" />'
+ '<br />'
+ '<div id="favtext" style="color: #D20425;">'
+ 'Add to your favorites.'
+ '</div>');
firstCheck();
} else if (loggedin == 0)
{
document.writeln('<img id="favorite" style="cursor: pointer;" src="http://www.********.com/images/favorite-off.png" alt="Favorite" />'
+ '<br />'
+ '<div id="favtext" style="color: #D20425;">'
+ '<a style="color: #800000; font-weight: bold;" href="' + thisurl + '/wp-login.php">Log in</a> to add favorites.'
+ '</div>');
}
PHP:
<?php
include('connect.php');
$salt = "********";
$perform = $_POST[0];
$place = $_POST[1];
$user = $_POST[2];
$usercrypt = crypt(md5($user),$salt);
$placeid = trim($place,",");
function checkNow()
{
global $usercrypt;
global $place;
global $conn;
$urow = mysqli_query($conn, "SELECT Users.User FROM Users WHERE Users.User='" . $usercrypt . "';");
if (mysqli_num_rows($urow) > 0)
{
$favcheck = mysqli_query($conn, "SELECT Users.Favorites FROM Users WHERE Users.User='" . $usercrypt . "';");
$favcheck = mysqli_fetch_array($favcheck);
$favcheck = $favcheck[0];
if (strpos($favcheck, $place) !== false)
{
$answer = 'found';
}
else
{
$answer = 'notfound';
}
}
else
{
$answer = 'nouser';
}
return array($answer,$favcheck);
unset($answer);
}
if ($perform == "0")
{
$sendback = checkNow();
echo $sendback[0];
unset($sendback);
}
if ($perform == "1")
{
global $usercrypt;
global $conn;
mysqli_query($conn, "INSERT INTO Users (User) VALUES ('" . $usercrypt . "')");
}
if ($perform == "2")
{
$sendback = checkNow();
global $place;
global $placeid;
global $usercrypt;
global $conn;
$currentnum = mysqli_query($conn, "SELECT Places.Favorites FROM Places WHERE Places.PlaceID=" . $placeid);
$currentnum = mysqli_fetch_array($currentnum);
$currentnum = $currentnum[0];
if ($sendback[0] == 'found')
{
$currentnum--;
$change = str_replace($place,'',$sendback[1]);
mysqli_query($conn, "UPDATE Users SET Favorites='" . $change . "' WHERE User = '" . $usercrypt . "'");
mysqli_query($conn, "UPDATE Places SET Places.Favorites=" . $currentnum . " WHERE Places.PlaceID =" . $placeid);
$answer = 'subtracted';
}
if ($sendback[0] == 'notfound')
{
$currentnum++;
$change = $sendback[1] . $place;
mysqli_query($conn, "UPDATE Users SET Favorites='" . $change . "' WHERE User = '" . $usercrypt . "'");
mysqli_query($conn, "UPDATE Places SET Places.Favorites=" . $currentnum . " WHERE Places.PlaceID =" . $placeid);
$answer = 'added';
}
return $answer;
unset($answer);
}
unset($_POST);
?>
这有点混乱:您正在混合异步和同步 javascript,您永远不知道什么是什么以及您处于什么状态。除此之外,您使用的是全局 javascript 在将它们用于异步请求时同步重置和覆盖的变量。
例如检查您的 firstCheck()
函数:这将重置您的 xmlhttp
变量(在另一个函数中...)并发出异步请求,但您已经在检查 return 检查 z
值时在下一行中显示异步请求的值。该值(另一个全局变量...)只会在您的异步调用完成时设置,以便逻辑在那里没有位置。
您需要重新考虑您的体系结构,记住每次您发出 ajax 请求时,结果不会立即可用,将触发一个单独的事件 - readyState
更改 -只有这样,您才能使用来自服务器的 returned 信息做您想做的事情。
z
的值将在 xmlhttp 对象接收就绪状态更改之前进行评估。您需要将所有处理返回值的代码放入 onreadystatechange
函数本身,因为这是唯一保证在您收到异步响应后调用的函数。
你可以这样做:
var xmlhttp = false;
// The rest of your code, but remove the `onreadystatechange` assignment from ajaxSession()
// ...
// ...
function heartCheck() {
perform = 2;
stateCheck();
xmlhttp.onreadystatechange = function() {
z = xmlhttp.responseText;
if (z == 'added')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-on.png";
document.getElementById("favtext").innerHTML="This is a favorite!";
}
if (z == 'subtracted')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-off.png";
document.getElementById("favtext").innerHTML="Add to your favorites.";
}
}
}
每次要评估 AJAX 响应时,您都需要执行这样的处理程序。
像我上面那样在脚本的开头声明全局变量也是最清楚的——正如@jeroen 提到的,这不是明确要求的,但这是一个很好的做法,可以帮助您跟踪范围。令人困惑的是 z
仅在 xmlhttp.onreadystatechange
函数内定义,但您在整个脚本中全局使用它。因此,一个简单的提示是将 var z = ''
放在 JavaScript 的开头,以使您的意图更加清晰(对您自己和可能正在查看您的代码的其他人来说:))
我有一个 AJAX 会话,它在页面加载时调用一次,在单击后再次调用。第二次它没有获得就绪状态更改,所以我决定通过在函数中放置一个警告框来测试它。警告框显示在页面加载上。但是在点击时它没有显示 - 得到这个 - 即使 PHP 端执行。更令人费解的是,如果我尝试测量就绪状态,它永远不会出现(不是 0、1、2、3 或 4 - 警告框甚至不会出现),而且我没有得到 return 文本.
我最终想要实现的是 xmlhttp.responseText 到 return 的值,就像它在页面加载时所做的那样。我错过了什么?
JavaScript:
function ajaxSession()
{
alert();
xmlhttp = undefined;
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)
{
z = xmlhttp.responseText;
}
}
}
function stateCheck()
{
ajaxSession();
xmlhttp.open('POST', thisurl + '/favoritecheck.php',false);
xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttp.send("0=" + perform + "&1=" + thisplace + ",&2=" + thisusername);
}
function firstCheck()
{
perform = 0;
stateCheck();
if (z == 'found')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-on.png";
document.getElementById("favtext").innerHTML="This is a favorite!";
}
if ( z == 'nouser')
{
perform = 1;
stateCheck();
}
}
function heartCheck()
{
perform = 2;
stateCheck();
if (z == 'added')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-on.png";
document.getElementById("favtext").innerHTML="This is a favorite!";
}
if (z == 'subtracted')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-off.png";
document.getElementById("favtext").innerHTML="Add to your favorites.";
}
}
if (loggedin == 1)
{
document.writeln('<img id="favorite" style="cursor: pointer;" onclick="heartCheck()" src="http://www.********.com/images/favorite-off.png" alt="Favorite" />'
+ '<br />'
+ '<div id="favtext" style="color: #D20425;">'
+ 'Add to your favorites.'
+ '</div>');
firstCheck();
} else if (loggedin == 0)
{
document.writeln('<img id="favorite" style="cursor: pointer;" src="http://www.********.com/images/favorite-off.png" alt="Favorite" />'
+ '<br />'
+ '<div id="favtext" style="color: #D20425;">'
+ '<a style="color: #800000; font-weight: bold;" href="' + thisurl + '/wp-login.php">Log in</a> to add favorites.'
+ '</div>');
}
PHP:
<?php
include('connect.php');
$salt = "********";
$perform = $_POST[0];
$place = $_POST[1];
$user = $_POST[2];
$usercrypt = crypt(md5($user),$salt);
$placeid = trim($place,",");
function checkNow()
{
global $usercrypt;
global $place;
global $conn;
$urow = mysqli_query($conn, "SELECT Users.User FROM Users WHERE Users.User='" . $usercrypt . "';");
if (mysqli_num_rows($urow) > 0)
{
$favcheck = mysqli_query($conn, "SELECT Users.Favorites FROM Users WHERE Users.User='" . $usercrypt . "';");
$favcheck = mysqli_fetch_array($favcheck);
$favcheck = $favcheck[0];
if (strpos($favcheck, $place) !== false)
{
$answer = 'found';
}
else
{
$answer = 'notfound';
}
}
else
{
$answer = 'nouser';
}
return array($answer,$favcheck);
unset($answer);
}
if ($perform == "0")
{
$sendback = checkNow();
echo $sendback[0];
unset($sendback);
}
if ($perform == "1")
{
global $usercrypt;
global $conn;
mysqli_query($conn, "INSERT INTO Users (User) VALUES ('" . $usercrypt . "')");
}
if ($perform == "2")
{
$sendback = checkNow();
global $place;
global $placeid;
global $usercrypt;
global $conn;
$currentnum = mysqli_query($conn, "SELECT Places.Favorites FROM Places WHERE Places.PlaceID=" . $placeid);
$currentnum = mysqli_fetch_array($currentnum);
$currentnum = $currentnum[0];
if ($sendback[0] == 'found')
{
$currentnum--;
$change = str_replace($place,'',$sendback[1]);
mysqli_query($conn, "UPDATE Users SET Favorites='" . $change . "' WHERE User = '" . $usercrypt . "'");
mysqli_query($conn, "UPDATE Places SET Places.Favorites=" . $currentnum . " WHERE Places.PlaceID =" . $placeid);
$answer = 'subtracted';
}
if ($sendback[0] == 'notfound')
{
$currentnum++;
$change = $sendback[1] . $place;
mysqli_query($conn, "UPDATE Users SET Favorites='" . $change . "' WHERE User = '" . $usercrypt . "'");
mysqli_query($conn, "UPDATE Places SET Places.Favorites=" . $currentnum . " WHERE Places.PlaceID =" . $placeid);
$answer = 'added';
}
return $answer;
unset($answer);
}
unset($_POST);
?>
这有点混乱:您正在混合异步和同步 javascript,您永远不知道什么是什么以及您处于什么状态。除此之外,您使用的是全局 javascript 在将它们用于异步请求时同步重置和覆盖的变量。
例如检查您的 firstCheck()
函数:这将重置您的 xmlhttp
变量(在另一个函数中...)并发出异步请求,但您已经在检查 return 检查 z
值时在下一行中显示异步请求的值。该值(另一个全局变量...)只会在您的异步调用完成时设置,以便逻辑在那里没有位置。
您需要重新考虑您的体系结构,记住每次您发出 ajax 请求时,结果不会立即可用,将触发一个单独的事件 - readyState
更改 -只有这样,您才能使用来自服务器的 returned 信息做您想做的事情。
z
的值将在 xmlhttp 对象接收就绪状态更改之前进行评估。您需要将所有处理返回值的代码放入 onreadystatechange
函数本身,因为这是唯一保证在您收到异步响应后调用的函数。
你可以这样做:
var xmlhttp = false;
// The rest of your code, but remove the `onreadystatechange` assignment from ajaxSession()
// ...
// ...
function heartCheck() {
perform = 2;
stateCheck();
xmlhttp.onreadystatechange = function() {
z = xmlhttp.responseText;
if (z == 'added')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-on.png";
document.getElementById("favtext").innerHTML="This is a favorite!";
}
if (z == 'subtracted')
{
document.getElementById("favorite").src="http://www.********.com/images/favorite-off.png";
document.getElementById("favtext").innerHTML="Add to your favorites.";
}
}
}
每次要评估 AJAX 响应时,您都需要执行这样的处理程序。
像我上面那样在脚本的开头声明全局变量也是最清楚的——正如@jeroen 提到的,这不是明确要求的,但这是一个很好的做法,可以帮助您跟踪范围。令人困惑的是 z
仅在 xmlhttp.onreadystatechange
函数内定义,但您在整个脚本中全局使用它。因此,一个简单的提示是将 var z = ''
放在 JavaScript 的开头,以使您的意图更加清晰(对您自己和可能正在查看您的代码的其他人来说:))