【问题标题】:Two Ajax calls from different sources causing one to silently fail [closed]来自不同来源的两个 Ajax 调用导致一个静默失败 [关闭]
【发布时间】:2014-05-12 22:01:11
【问题描述】:

编辑:刚刚遇到了一个问题,周末我刚刚在 iPhone 上运行了这个程序,出于好奇,我同时在两部手机上运行了它,它运行正常。所以当一部手机是 iPhone (iOS 6) 而另一部是 HTC One (Android 4.3) 时,它运行得很愉快(正如我第一次预期的那样)。然而,这是在另一个人的 WIFI 上。我的家庭 WIFI 是否会成为阻止两台设备访问同一位置的一个因素? (我使用的第二部手机不工作时是三星 Galaxy Ace 2 (Android 2.3))

所以我遇到了这个问题。我正在使用 PhoneGap 并想出一个基本的测验系统来解决问题。我已经让它工作了,我玩得很开心。它本质上是通过一个 Web 控制台工作的,我可以在其中设置测验和循环问题,并通过对底层数据库的一系列不那么复杂的状态更新,我使用手机上的 Ajax 调用来读取状态并显示问题或等待下一个。

基本调用是:

$(function checkForQuestion() {
    var postData = "stuff needed in called PHP";
    $.ajax({
        type: "POST",               
        data: postData,             
        url: "my called php",           
        success: function(data){                
        var result = JSON.parse(data);
        if (result == "question") {
            --Display Question
        } else {
            setTimeout(checkForQuestion, 1000);
            return false;
        }
    });         
    return false;
}); 

根据我有限的经验,这似乎是 Ajax 的一般用途,如果需要等待新状态,则需要递归回调。

到目前为止,这还不是全部,而是我正在做的事情的品尝者。它与一台移动设备和一个愉快地完成测验的网络控制台配合得非常好。

当我尝试添加第二个手机(甚至还没有尝试过三个)时,会发生第二个手机在它应该调用这个 ajax 的地方静默失败。现在第二部手机可以很高兴地自行处理,所以它不应该是硬件问题。 PHP 中没有抛出任何错误,并且通过一些日志记录我找不到任何明显失败的东西。

此时我想,我的网络主机上的连接可能存在限制(我只是使用我用来测试的共享服务器网络主机),但仅限于 20 个条目使用 Cloud Linux LVE 进行处理。但是,这不应该排除两部手机大致同时调用同一个 PHP(通过 wifi)。它应该只同时运行调用,并且其中一个会比另一个返回稍快(或者这是我的理解)。

我想这可能是我正在使用的 MySQL 数据库上的一个锁,不允许多个用户/PHP 大致同时查询它,但是 PHP 的连续性应该排除这种情况,并且一些谷歌搜索向我保证呼叫将被排队。

我猜正在发生的事情是两个调用进来并且没有返回任何错误,一个与另一个默默地冲突导致失败,但我不知道如何找到失败并修复它。

有什么建议吗?

请求实际代码:

$(function () {
    $(document).on("pagebeforeshow", "#page6", function () {
        document.getElementById("mob_user_name2").innerHTML = window.localStorage.getItem("mob_local_login_name");

        $(function checkForQuestion() {
            //sort out the data to be posted
            var postData = "mob_quizwait_quizcode=" . concat(window.localStorage.getItem("mob_local_quiz_code"), "&mob_quizwait_email=", window.localStorage.getItem("mob_local_login_email"), "&mob_quizwait_password=", window.localStorage.getItem("mob_local_login_password"), "&mob_quizwait_questionid=", window.localStorage.getItem("mob_question_id"));

            $.ajax({
                type: "POST",               
                data: postData,             
                url: "url of php",          
                success: function(data){                
                    var mob_quizwait_data = JSON.parse(data);
                    if (mob_quizwait_data.mob_quizwait_success == "mob quizwait go") {
                        window.localStorage.setItem("mob_question_id", mob_quizwait_data.mob_quizwait_questionid);
                        window.localStorage.setItem("mob_question_score", mob_quizwait_data.mob_quizwait_score);
                        window.localStorage.setItem("mob_question_category", mob_quizwait_data.mob_quizwait_category);
                        window.localStorage.setItem("mob_question_question", mob_quizwait_data.mob_quizwait_question);
                        window.localStorage.setItem("mob_answer1", mob_quizwait_data.mob_quizwait_correct);
                        window.localStorage.setItem("mob_answer2", mob_quizwait_data.mob_quizwait_wrong1);
                        window.localStorage.setItem("mob_answer3", mob_quizwait_data.mob_quizwait_wrong2);
                        window.localStorage.setItem("mob_answer4", mob_quizwait_data.mob_quizwait_wrong3);
                        $.mobile.changePage("#page7", {transition:"slide", changeHash:false});
                    } else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait stay") {
                        setTimeout(checkForQuestion, 1000);
                        return false;
                    } else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait intermission") {
                        document.getElementById("mob_intermission").innerHTML = "Intermission";
                        $.mobile.changePage("#page6", {transition:"none", changeHash:false});
                    } else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait finish") {
                        $.mobile.changePage("#page8", {transition:"slide", changeHash:false});
                    } else {
                        navigator.notification.alert("Status Check Failed. Please Try Again.", function(){}, "Alert", "OK");
                    }
                }       
            });         
            return false;
        }); 
    });
});

还有 PHP:

<?PHP

include '../open.php';

//take in POST variables
$quizcode = $link->real_escape_string($_POST["mob_quizwait_quizcode"]);
$email = $link->real_escape_string($_POST["mob_quizwait_email"]);
$password = $link->real_escape_string($_POST["mob_quizwait_password"]);
$questionid1 = $link->real_escape_string($_POST["mob_quizwait_questionid"]);

$quizid = 0;
$status = "X";
$questionid = 0;

$sql = "SELECT QUIZ_ID FROM B_QUIZ WHERE QUIZ_CODE = '$quizcode'";
$res = $link->query($sql);

while ($row = $res->fetch_array()) {
    $quizid = $row['QUIZ_ID'];
}

$sql = "SELECT USER_ID FROM A_USER WHERE USER_EMAIL = '$email' AND USER_PASSWORD = '$password'";
$res = $link->query($sql);

while ($row = $res->fetch_array()) {
    $userid = $row['USER_ID'];
}

$sql = "SELECT QUIZ_STATUS, IFNULL(QUESTION_ID, 0) AS QUESTION_ID FROM B_GAME WHERE QUIZ_ID = $quizid";
$res = $link->query($sql);

while ($row = $res->fetch_array()) {
     $status = $row['QUIZ_STATUS'];
 $questionid = $row['QUESTION_ID'];
}

if ($questionid == $questionid1) {
$questionid = 0;
}

if ($status != "F") {
if ($quizid != 0 && $status != "X") {
    //get details to be written to the profile page
    if ($questionid != 0) {

        $sql = "SELECT SCORE FROM B_PARTICIPANT WHERE USER_ID = $userid AND QUIZ_ID = $quizid";
        $res = $link->query($sql);

        while ($row = $res->fetch_array()) {
            $score = $row['SCORE'];
        }

        $sql = "SELECT b.QUESTION_ID, c.CATEGORY, b.QUESTION, b.CORRECT_ANSWER, b.WRONG_ANSWER_1, b.WRONG_ANSWER_2, b.WRONG_ANSWER_3
                    FROM B_GAME a, B_QUESTION b, D_CATEGORY c
                    WHERE a.QUESTION_ID = b.QUESTION_ID
                    AND b.CATEGORY_ID = c.CATEGORY_ID
                    AND a.QUIZ_ID = $quizid";
        $res = $link->query($sql);

        while ($row = $res->fetch_array()) {
            $questionid = $row['QUESTION_ID'];
            $category = $row['CATEGORY'];
            $question = $row['QUESTION'];
            $correct = $row['CORRECT_ANSWER'];
            $wrong1 = $row['WRONG_ANSWER_1'];
            $wrong2 = $row['WRONG_ANSWER_2'];
            $wrong3 = $row['WRONG_ANSWER_3'];
        }

        if ($status == "R") {
            $arr = array("mob_quizwait_success" => "mob quizwait go", 
                         "mob_quizwait_questionid" => $questionid,
                         "mob_quizwait_score" => $score, 
                         "mob_quizwait_category" => $category, 
                         "mob_quizwait_question" => $question, 
                         "mob_quizwait_correct" => $correct, 
                         "mob_quizwait_wrong1" => $wrong1, 
                         "mob_quizwait_wrong2" => $wrong2,
                         "mob_quizwait_wrong3" => $wrong3);
            echo json_encode($arr);
        } else if ($status == "N") {
            $arr = array("mob_quizwait_success" => "mob quizwait stay");
            echo json_encode($arr);
        } else if ($status == "I") {
            $arr = array("mob_quizwait_success" => "mob quizwait intermission");
            echo json_encode($arr);
        }
    } else {
        $arr = array("mob_quizwait_success" => "mob quizwait stay");
        echo json_encode($arr);
    }
} else {
    $arr = array("mob_quizwait_success" => "mob quizwait failed");
    echo json_encode($arr);
}

} else {
$arr = array("mob_quizwait_success" => "mob quizwait finished");
echo json_encode($arr);
}

include '../close.php';

?>

open.php:

<?PHP

//DATABASE DETAILS//
$DB_ADDRESS = "yeah";
$DB_USER = "not";
$DB_PASS = "gonna";
$DB_NAME = "do it";

//Connect to the MySQL database
$link = new mysqli($DB_ADDRESS, $DB_USER, $DB_PASS, $DB_NAME);  

if (mysqli_connect_errno()) {

        printf("Connect Failed: %s\n", mysqli_connect_error());
        exit();

}                       

?>

关闭.php:

<?PHP
mysqli_close($link);
?>

【问题讨论】:

  • 发布您的真实代码。所有明显错误的相关部分都已删除。
  • 在第二部手机上获取页面的调用是否立即失败,或者只是无限期地旋转?您还在应用程序中的任何地方使用 PHP 会话(也就是说,您是否在任何地方调用 session_start())?
  • 抱歉刚刚注意到您的评论。问题是第二个电话似乎默默地失败了,所以我不知道它是失败还是无限期地旋转。没有给出 PHP 错误。看起来,没有任何东西被返回到手机,它只是坐在屏幕上,用来调用 PHP 而没有任何反应。在整个设置中的任何地方都没有使用会话。为了清楚起见 - 我认为我的问题归结为如何更好地想象我的失败,以便我可以解决它。
  • 你有没有想过在你的任何查询中使用or die($link-&gt;error); 来实际查看是否存在 MySQL 错误,因为你没有我怀疑你会从中看到错误。您可以在代码中为每个阶段添加一些行(例如echo "first query\n";),这样它会告诉您如果失败,它会在失败前走了多远,并且可能会将其输出到文件而不是打印到屏幕上。此外,您可能会更好地使用 async AJAX。
  • 这个应用程序的 URL 是什么?我可以摆弄一下,看看这些请求是如何进行的。此外,您可能想要做的事情是覆盖主机正在执行的所有错误处理,并在调试此问题时直接输出给用户。为此:error_reporting(E_ALL); ini_set('display_errors', 1);

标签: php mysql ajax


【解决方案1】:

静默失败可能是因为处理ajax调用时出现服务器错误。

error 处理程序添加到 ajax 调用。

$.ajax({
   type: "POST",
   data: postData,
   url: 'url of php',
   success: successFunction(),
   error: function(xhr, status, err) { alert("Ajax request failed"); }
});

您可能需要单步调试 PHP 代码或添加额外的日志记录才能查看应用程序的流程。

【讨论】:

  • 已使用且未标记任何错误。
  • 荣耀!进步!我现在看到失败了。起初我没有看到它,因为它会在失败之前等待一段时间。我将错误更改为: error: function(xhr, status, error) { var err = eval("(" + xhr.responseText + ")"); alert(err.Message);} 这又回来了“与服务器的连接不成功。(file:///android_asset/www/index.html)”有人知道这告诉我什么吗?
  • @ashcanschool 好像网址不正确。您是否使用完整的表格,例如http://www.website.com/script.php
  • 是的,我必须使用完整的 URL,否则它将无法正常工作,请记住,这适用于其他手机以及在其他手机不使用时静默失败的手机。昨晚深夜查找错误似乎表明它正在超时。
  • @ashcanschool 超时只是表明它未能加载资源。有问题的资源的 url 无效,因此失败 - 它似乎使用了 file:/// 前缀,该前缀通常用于加载本地文件而不是网页。这就是我要求您检查 url 有效性的原因。这可能取决于设备配置或其他一些设置。为确保与任何设备的最大兼容性,请使用完整的网址 - 出错的可能性较小。
【解决方案2】:

试试:

<script>
var st_flag = true;

$(function () {
    $(document).on("pagebeforeshow", "#page6", function () {
        document.getElementById("mob_user_name2").innerHTML = window.localStorage.getItem("mob_local_login_name");      

        $(function checkForQuestion() {    

          if(!st_flag)
          {
             setTimeout(checkForQuestion, 1000); 
          } 

            //sort out the data to be posted
            var postData = "mob_quizwait_quizcode=" . concat(window.localStorage.getItem("mob_local_quiz_code"), "&mob_quizwait_email=", window.localStorage.getItem("mob_local_login_email"), "&mob_quizwait_password=", window.localStorage.getItem("mob_local_login_password"), "&mob_quizwait_questionid=", window.localStorage.getItem("mob_question_id"));

            $.ajax({
                type: "POST",               
                data: postData,             
                url: "url of php",  

               st_flag = false;         

                success: function(data){                
                    var mob_quizwait_data = JSON.parse(data);
                    if (mob_quizwait_data.mob_quizwait_success == "mob quizwait go") {
                        window.localStorage.setItem("mob_question_id", mob_quizwait_data.mob_quizwait_questionid);
                        window.localStorage.setItem("mob_question_score", mob_quizwait_data.mob_quizwait_score);
                        window.localStorage.setItem("mob_question_category", mob_quizwait_data.mob_quizwait_category);
                        window.localStorage.setItem("mob_question_question", mob_quizwait_data.mob_quizwait_question);
                        window.localStorage.setItem("mob_answer1", mob_quizwait_data.mob_quizwait_correct);
                        window.localStorage.setItem("mob_answer2", mob_quizwait_data.mob_quizwait_wrong1);
                        window.localStorage.setItem("mob_answer3", mob_quizwait_data.mob_quizwait_wrong2);
                        window.localStorage.setItem("mob_answer4", mob_quizwait_data.mob_quizwait_wrong3);
                        $.mobile.changePage("#page7", {transition:"slide", changeHash:false});

                        st_flag = true;

                    } else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait stay") {
                        setTimeout(checkForQuestion, 1000); 
                        return false;
                    } else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait intermission") {
                        document.getElementById("mob_intermission").innerHTML = "Intermission";
                        $.mobile.changePage("#page6", {transition:"none", changeHash:false});
                    } else if (mob_quizwait_data.mob_quizwait_success == "mob quizwait finish") {
                        $.mobile.changePage("#page8", {transition:"slide", changeHash:false});
                    } else {
                        navigator.notification.alert("Status Check Failed. Please Try Again.", function(){}, "Alert", "OK");
                    }
                }       
            });         
            return false;
        }); 
    });
});
</script>

等待第一次调用完成。

【讨论】:

  • 您能解释一下这与我的设置有何不同吗?我设置了它,以便在加载页面时调用该函数,其中一部分是 AJAX 调用,如果调用返回一个答案我继续它,如果它返回并说等待然后我等待 1 秒然后再次递归调用AJAX,它必须在调用之前完成。它永远不会踩到自己的脚趾并发出两个看起来你的代码试图停止的调用。是我错了吗?
  • OK 这个已经试过了,没有效果。
【解决方案3】:

尽管你的问题本质上很复杂,我没有理由得出我要说的结论,但我的赌注是session.auto_start

正如我所见,您的代码中没有使用 session ,在您的情况下,启动它可能是个问题。将 session.auto_start 设置为 false,这样您的代码将根本不使用会话,然后测试您的代码。这是一个很长的镜头,但这是我所拥有的最好的。

为了解释我自己,php 默认使用文件进行会话。它通过以独占模式打开文件来实现。这意味着如果服务器上正在运行一个请求,则具有相同 session_id 的第二个请求将被阻止,直到第一个请求实现。因此,每个浏览器一次只能在服务器上执行一个请求。我知道您的 javascript 在返回第一个请求之前不会发出第二个请求,但正如我所说,您的问题很复杂,这是我能想到的唯一猜测,我相信它值得一试。

所以我的解决方案是:确保您根本没有使用会话

【讨论】:

  • 检查并确定 session.auto_start 设置为 0,所以没有会话。
【解决方案4】:

正如 Kami 所说,我认为应该只在服务器端 (PHP) 存在一些问题。而且很多时候,由于服务器设置,PHP 不习惯显示错误。我建议您检查 apache 错误日志,以便了解是否存在任何未显示的错误。要检查这一点,只需加载有问题的 URL,然后检查通常出现在 var/log/ 文件夹中的错误日志。

【讨论】:

  • 查看了日志,一无所获。
【解决方案5】:

在您编辑后我有一个奇怪的建议。 Wifi 热点通过 NAT 隐藏真实地址,因此从服务器的角度来看,您的两个设备都具有相同的 IP 地址。服务器将答案发送到您的 Wifi 点,并将数据包路由到真实地址。有时我的包裹丢失了,但我不记得所有包裹都丢失的情况。

您应该从两个设备请求页面并在服务器端记录脚本的工作结果。如果有 2 个请求并且所有数据库请求都正常工作,则意味着您的一个客户没有得到响应。可能是因为你的路由器,可能是 NAT

【讨论】:

    【解决方案6】:

    这原来是 Web 主机提供商的一个未知问题。尽管有十几个详细的请求,询问他们那边是什么阻止了事情,但我总是被提到我自己的设备或自己的代码有什么问题。

    设置自己的 VPS 并立即更改 -o 我有一个工作系统,无需修改代码或设备。

    我不喜欢通过指责别人来掩盖自己无能的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多