【问题标题】:AJAX submit data to PHP in JSONAJAX 以 JSON 格式向 PHP 提交数据
【发布时间】:2014-12-29 13:05:31
【问题描述】:

我正在构建一个测验,我现在正在做的是处理用户的输入并使用我的数据库中的答案表检查用户的提交并将分数返回给用户。

我的测验采用多项选择的形式供用户选择,每个选项都有自己的价值。我为捕获数据所做的是将表单数据序列化并将所有表单数据存储在一个对象中。该对象看起来像这样:

{ 问题1:'1',问题2:'2',问题3:'3',问题4:'4',问题5:'5'}

因此,它将问题和用户答案存储为键值对,问题编号在前,用户选择的选项在后。正如您从下面的代码中看到的那样,我正在使用 .each 取出键值对,而我想做的是每次 .each 运行时,将 ajax 命令运行到外部 checkanswer.php 脚本以进行验证用户选择的选项。每次服务器返回匹配项时,php 都会向 ajax 返回一个文本字符串“正确”,然后将 1 增加到创建的计数变量。我还在下面附加了 php 脚本。在@barmar 的建议下,我已经完全删除了 json,但是 .each 下的 count 变量仍然没有根据从 ajax 调用返回的正确答案的数量给出正确的数字。 ++ 在阅读了有关 ajax 工作方式的更多信息后,似乎 ajax 不等待提交处理程序,因此我必须更改代码。一种方法是实际发送整个字符串并让 php 循环遍历键值对并在那里进行计数并将值返回给 ajax。大家觉得呢?

                 <script>
            $('#quizform').submit(function() {
            var data = $(this).serializeArray();
            count = 0;
            $.each(data, function(i, el) {
                //display the key and value pair
                var k = el.name;
                 var v = el.value;

                 var request = $.ajax({
                        url: "checkanswer.php",
                        type: "POST",
                        data:{ k:k, v:v},
                        dataType:"text",


                   success: function(data) { 
                   if (data=="correct") {
                    count++;


                   } 
                   },
                   error: function(request, err){ 


                  alert(err);



                   }
                 });


});
            alert(count);
             return false;
});



            </script>

PHP 脚本:

    <?php
session_start();
include_once("config.php");
if (isset($_POST['k']) && isset($_POST['v'])){

    $questionid=$_POST['k'];
    $option=$_POST['v'];

    $result=mysqli_query($mysqli, "SELECT COUNT(*) FROM answer WHERE question_id = ".$questionid." AND optionid = ".$option."");

    if($result==0) {
        echo"wrong";

    }else if ($result == 1) {

        echo"correct";

    }



}

?>

我已经编辑了上面的代码

【问题讨论】:

  • 您需要设置您的 HTTP“Content-Type”标头。我建议使用 Chrome 调试器并转到网络面板并使用“保留日志”复选框来查看服务器返回的内容。需要是 JSON 响应。
  • 是的,我认为它与标题有关,目前每当我提交表单时,它都会将我重定向到我页面中找到的另一个 php 标题,这对我来说很奇怪
  • 查看 config.php 文件中的内容,可能包含标题并导致问题

标签: javascript php jquery ajax json


【解决方案1】:

json 是一个字符串。 $.each() 的参数必须是数组或对象。你不需要创建一个 JSON 字符串,你应该直接循环 obj

$.each(obj, function(k, v) {
    ...
});

其实也没有理由去创建obj,也可以循环遍历data

$.each(data, function(i, el)
    var k = el.name;
    var v = el.value;
    ...
});

最后,这将不是 JSON。 $.ajax 使用 x-www-form-urlencoded 格式,PHP 会自动解码。所以你不应该在 PHP 中使用json_decode()

【讨论】:

  • 嗨,这澄清了很多关于 JSON 的问题,但计数仍然总是返回 0,即使我有正确的答案,因为你提到我不需要使用 JSON,这意味着我必须从 PHP 文件中删除 json_decode,并将 ajax 调用中的数据类型更改为文本?
  • 是的,我已删除所有 json_decode,并将数据类型更改为文本,但是,我认为循环仍然无法正常工作,因为它没有循环所有问题(假设我有 5 个问题),它不是循环遍历每个问题并为每个问题触发 ajax 请求以在有正确答案时增加计数。
  • AJAX 中的第一个 A 代表异步。所有 AJAX 请求同时触发,然后 submit 处理程序返回,它不等待响应。见stackoverflow.com/questions/14220321/…
  • 不是为每个问题触发单独的 AJAX 请求,而是在一个请求中发送所有问题。然后success函数就可以处理所有的结果,显示你想要的。
  • 我猜这意味着在一个字符串中发送所有键值对,例如,q1:1、q2:2、q3:3,然后在我的 php 代码中执行一个 for 循环来检查一个加一并在 php 脚本中计数?
【解决方案2】:

在我看来你的代码格式不正确,你也应该用你的 HTML 显示你的完整代码,我也不知道你为什么要制作一个问题 id 数组,如果它们可以在不循环的情况下发送到服务器它们与元素的维度数组。

并在 mysql 中使用 IN 运算符,因为您正在使用返回数组或对象的 json_decode(),因此请尝试您的查询,

$result=mysqli_query($mysqli, "SELECT COUNT(*) FROM answer WHERE question_id IN (".$questionid.") AND optionid IN (".$option.")");

例如,您有questionid as array of html elements,然后将其传递给 ajax 之类的,

$('#form').on('submit',function(e){
    e.preventDefault();
    var data=$(this).serialize();
    $.ajax({...});/// using post method
    return false;
});

php-mysql query 中使用它,

$sqlQuery = "SELECT COUNT(*) FROM answer WHERE question_id IN (".implode(',',$_POST['questionid'].") ";

【讨论】:

  • 您好,我想我不能使用 jsondecode,因为它会从 ajax 调用返回一个解析错误
  • hmm,你认为我可以运行一个 for 循环,然后当 COUNT 返回 1 时,然后 count++ 或 implode 是这里最好的解决方案,因为我的字符串将包含多个键值对
  • 嗯,感谢您的链接,但我不太确定如何获取这种格式的字符串 {q1:1, q2:2, q3:2, q4:3}
【解决方案3】:

您似乎对 javascripts 的异步行为有疑问。您无法猜测 count 的增量何时在您的代码中完成,因为 ajax 调用是异步的。

改为使用jQuery.when() 来确定所有ajax 调用何时完成,并在完成时使用count 变量..

var count = 0;
var ajaxCalls = [];
$.each(data, function(i, el) {
    //display the key and value pair
    var k = el.name;
    var v = el.value;

    ajaxCalls.push($.ajax({
                    url: "checkanswer.php",
                    type: "POST",
                    data:{ k:k, v:v},
                    dataType:"text",
                    success: function(data) { 
                      if (data=="correct") {
                        count++;
                      } 
                    },
                    error: function(request, err){ 
                            alert(err);
                    }
                  }));
});

$.when.apply(null, ajaxCalls ).done(function () { alert(count);});

【讨论】:

  • **var json = JSON.stringify( obj );** 在循环中应该做什么?
  • 您好,正如@barmar 提到的,我明白我不再需要使用 JSON,我将在上面编辑我的代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多