2015-04-17 92 views
2

我有被調用一次在頁面加載和點擊後再次AJAX的會話。它沒有第二次做好現成的改變,所以我決定通過在函數中放置一個警告框來測試它。警告框顯示在頁面加載。但是點擊它不會顯示出來 - 即使PHP端執行,也可以得到它。更令人費解的是,如果我嘗試測量就緒狀態,它永遠不會出現(不是0,1,2,3或4 - 警告框甚至不會顯示),並且我沒有收到回覆文本。AJAX會話調用兩次。它並不顯示一個警告,第二次

我最終想實現是像它的頁面加載xmlhttp.responseText返回一個值。我錯過了什麼?

的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) 
 
    { 
 
\t 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(); 
 
\t if (z == 'found') 
 
\t { 
 
\t document.getElementById("favorite").src="http://www.********.com/images/favorite-on.png"; 
 
\t document.getElementById("favtext").innerHTML="This is a favorite!"; 
 
\t } 
 
\t if (z == 'nouser') 
 
\t { 
 
\t perform = 1; 
 
\t stateCheck(); 
 
\t } 
 
} 
 

 
function heartCheck() 
 
{ 
 
perform = 2; 
 
stateCheck(); 
 
\t if (z == 'added') 
 
\t { 
 
\t document.getElementById("favorite").src="http://www.********.com/images/favorite-on.png"; 
 
\t document.getElementById("favtext").innerHTML="This is a favorite!"; 
 
\t } 
 
\t if (z == 'subtracted') 
 
\t { 
 
\t document.getElementById("favorite").src="http://www.********.com/images/favorite-off.png"; 
 
\t document.getElementById("favtext").innerHTML="Add to your favorites."; 
 
\t } 
 
} 
 

 

 

 
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 . "';"); 
 
\t if (mysqli_num_rows($urow) > 0) 
 
\t { 
 
\t $favcheck = mysqli_query($conn, "SELECT Users.Favorites FROM Users WHERE Users.User='" . $usercrypt . "';"); 
 
\t $favcheck = mysqli_fetch_array($favcheck); 
 
\t $favcheck = $favcheck[0]; 
 
\t \t if (strpos($favcheck, $place) !== false) 
 
\t \t { 
 
\t \t $answer = 'found'; 
 
\t \t } 
 
\t \t else 
 
\t \t { 
 
\t \t $answer = 'notfound'; 
 
\t \t } 
 
\t } 
 
\t else 
 
\t { 
 
\t $answer = 'nouser'; 
 
\t } 
 
return array($answer,$favcheck); 
 
unset($answer); 
 
} 
 
\t 
 
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]; 
 
\t if ($sendback[0] == 'found') 
 
\t { 
 
\t $currentnum--; 
 
\t $change = str_replace($place,'',$sendback[1]); 
 
\t mysqli_query($conn, "UPDATE Users SET Favorites='" . $change . "' WHERE User = '" . $usercrypt . "'"); 
 
\t mysqli_query($conn, "UPDATE Places SET Places.Favorites=" . $currentnum . " WHERE Places.PlaceID =" . $placeid); 
 
\t $answer = 'subtracted'; 
 
\t } 
 
\t if ($sendback[0] == 'notfound') 
 
\t { 
 
\t $currentnum++; 
 
\t $change = $sendback[1] . $place; 
 
\t mysqli_query($conn, "UPDATE Users SET Favorites='" . $change . "' WHERE User = '" . $usercrypt . "'"); 
 
\t mysqli_query($conn, "UPDATE Places SET Places.Favorites=" . $currentnum . " WHERE Places.PlaceID =" . $placeid); 
 
\t $answer = 'added'; 
 
\t } 
 
return $answer; 
 
unset($answer); 
 
} 
 

 
unset($_POST); 
 

 
?>

+0

你能張貼您的HTML爲好,好嗎? –

+0

只是一個說明:返回後的'unset'不會被執行,'global'只能在函數中使用。 – jcubic

+0

HTML太長而無法添加到帖子中。這是一個標準的WordPress頁面。這是頁面文本的內容: '?' – Ryan

回答

2

z的值將被評估之前 xmlhttp對象接收到readystate更改。您需要將處理返回值的所有代碼放入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的開始讓你的意圖更清晰(包括自己和別人誰可查看您的代碼:))

+0

謝謝您的全面解答。這已經讓我生氣了兩天了。我需要它解釋你做的方式。 – Ryan

+0

很好的答案,雖然個人,我會盡量避免整個全局變量混亂:-) – jeroen

+0

沒問題。祝你好運! jeroen的建議是非常真實的:爲避免混淆的意大利麪條,今後最好避免這種結構。 :) –

1

這是一個有點混亂:你是混合異步和SYNCHR onous JavaScript以某種方式永遠不會知道什麼是什麼以及處於什麼狀態。除此之外,您正在使用全局JavaScript變量,當您將它們用於異步請求時,它們會同步重置和覆蓋。

檢查例如您firstCheck()功能:這將重置您xmlhttp變量(在其他功能...),並作出異步請求,但你已經檢查您的異步請求的,當你的下一行返回值檢查z值。該值(另一個全局變量...)將只在異步調用完成時設置,以便邏輯沒有位置。

您需要重新考慮您的架構,切記每次發出ajax請求時,結果將不會立即可用,單獨的事件將觸發 - readyState更改 - 只有您可以執行您的操作想要從服務器返回的信息。

+1

謝謝你指出我剛纔沒有看到的缺陷缺陷。我是自學成才的(很明顯!),我真的需要一些外部視角。 – Ryan

相關問題