【问题标题】:jquery serialize and $.postjquery 序列化和 $.post
【发布时间】:2010-10-29 13:11:47
【问题描述】:

我正在尝试使用 jQuery 中的 $.post 方法从表单发送大量数据。我首先使用 serialize() 函数将所有表单数据变成一个长字符串,然后我将在服务器端展开。 奇怪的是,当我尝试使用 $.post 发送它时,它会将 serialize() 的结果附加到 URL,就好像我使用 GET 发送它一样。 有人知道为什么会这样吗?

这是 jquery:

$("#addShowFormSubmit").click(function(){
  var perfTimes = $("#addShowForm").serialize();
  $.post("includes/add_show.php", {name: $("#showTitle").val(), results: perfTimes }, function(data) {
    $("#addShowSuccess").empty().slideDown("slow").append(data);
  });
});  

这是 php:

$show = $_POST['name'];
$results = $_POST['results'];
$perfs = explode("&", $results);
foreach($perfs as $perf) {
    $perf_key_values = explode("=", $perf);
    $key = urldecode($perf_key_values[0]);
    $values = urldecode($perf_key_values[1]);
}
echo $key, $values;  

【问题讨论】:

    标签: php jquery serialization post get


    【解决方案1】:

    如果您使用<button> 元素来激活序列化和ajax,并且如果<button> 元素在form 元素内,那么button 会自动充当表单提交,不管其他什么。点击你用 jQuery 给它的赋值。

    type='提交'

    <button></button><button type='submit'></button> 是同一个东西。如果放置在<form> 元素中,他们将提交一个表单。

    type='按钮'

    <button type='button'></button> 不同。它只是一个普通的按钮,不会提交表单(除非你故意让它通过 JavaScript 提交表单)。

    如果 form 元素没有指定 action 属性,此提交只是将数据发送回同一页面。因此,您最终会看到页面刷新,以及出现在 URL 中的序列化数据,就好像您在 ajax 中使用了 GET 一样。

    可能的解决方案

    1 - 将<button> 设为button。如上所述,这将阻止按钮提交表单。

    之前:

    <form id='myForm'>
        <!--Some inputs, selects, textareas, etc here-->
        <button id='mySubmitButton'>Submit</button>
    </form>
    

    之后:

    <form id='myForm'>
        <!--Some inputs, selects, textareas, etc here-->
    <button type='button' id='mySubmitButton'>Submit</button>
    </form>
    

    2 - 将&lt;button&gt; 元素移到&lt;form&gt; 元素之外。这将阻止按钮提交表单。

    之前:

    <form id='myForm'>
        <!--Some inputs, selects, textareas, etc here-->
        <button id='mySubmitButton'>Submit</button>
    </form>
    

    之后:

    <form id='myForm'>
        <!--Some inputs, selects, textareas, etc here-->
    </form>
    <button id='mySubmitButton'>Submit</button>
    

    3 - 将preventDefault() 添加到按钮单击处理程序中以防止提交表单(这是默认操作):

    $("#addShowFormSubmit").click(function(event){
      event.preventDefault();
      var perfTimes = $("#addShowForm").serialize();
      $.post("includes/add_show.php", {name: $("#showTitle").val(), results: perfTimes },      function(data) {
        $("#addShowSuccess").empty().slideDown("slow").append(data);
      });
    });
    

    显然没有看到您的所有代码,我不知道您的问题是否属于这种情况,但我看到您描述的行为的唯一原因是因为提交按钮是 &lt;button&gt; 没有指定类型。

    【讨论】:

    • 实际上,真正的技巧是在您的点击处理程序中调用事件的preventDefault() 方法。这将阻止执行浏览器的本机操作。
    • 将按钮保留在表单内,但使用表单的提交处理程序并返回 false $('#myForm').submit(function() {var data = this.serialize(); $.post(this.attr('action'), data, function() {alert('done!')}); return false});
    • type="button" 添加到您的&lt;button&gt; 标记以避免表单提交。
    【解决方案2】:

    尝试使用 serializeArray() 而不是 serialize()。 serialize() 将产生一个 url 编码的查询字符串,而 serializeArray() 产生一个 JSON 数据结构。

    【讨论】:

      【解决方案3】:

      是什么让您相信数据已附加到 URL 中?

      无论如何,在表单数据本身中传递表单值不是更有意义吗?它将允许您跳过“爆炸”步骤:

      $("#addShowFormSubmit")
        .click(function() { 
            var perfTimes = $("#addShowForm").serialize(); 
            $.post("includes/add_show.php", 
               $.param({name: $("#showTitle").val()}) + "&" + perfTimes, 
               function(data) {...}); 
        });
      

      【讨论】:

      • 不应该是“&”而不是&吗?
      【解决方案4】:

      所以这可能有点迟钝,但我做了一个函数来帮助我做这件事,因为我厌倦了每次都做一堆修复。 serializeArray 有点烦人,因为它提供了一个对象集合,而我只想让 PhP 重建一个关联数组。下面的函数将遍历序列化数组,并仅在值存在时构建具有适当属性的新对象。

      首先,函数(它获取相关表单的 ID):

      function wrapFormValues(form) { 
          form = "#" + form.attr("id") + " :input";
          form = $(form).serializeArray();
          var dataArray = new Object();
      
          for( index in form)
          {   
              if(form[index].value)   {
                  dataArray[form[index].name] = form[index].value;    
              }
          }       
      
          return dataArray; 
      }
      

      在构建我的帖子时,我通常也使用一个对象,因为我通常在表单数据之前标记两个或三个其他值,我认为它看起来比内联定义它更简洁,所以最后一步看起来像这样:

      var payload = new Object(); 
      //stringify requires json2.js from http://www.json.org/js.html
      payload.data = JSON.stringify(data);
      
      $.post("page.php", payload,  
          function(reply) {
              //deal with reply.
          });
      

      在服务器端,您所要做的就是$payload = json_decode($_POST['data'], true),并且您拥有一个关联数组,其中键是表单字段的名称。

      完全免责声明,多选在这里可能不起作用,您可能只会得到列表中最后一个值。这也是专门为适合我的一个项目而创建的,因此您可能需要对其进行调整以适合您。例如,我对来自服务器的所有回复都使用 json。

      【讨论】:

        【解决方案5】:

        试试这个语法。我使用它来序列化表单并通过 ajax 调用 WCF 服务进行 POST。此外,您可以将其发送回单个 JSON 对象,而不是按照您的方式构建对象。试试这个:

        var serializedForm = serializedForm = $("#addShowForm").serializeArray();
        
        $.post("includes/add_show.php", 
            {
                "myObjectName": ("#showTitle").val(), results: perfTimes 
            }, function(data) 
                {
                    $("#addShowSuccess").empty()
                    .slideDown("slow")
                    .append(JSON.stringify(serializedForm)); 
                });
        

        【讨论】:

          【解决方案6】:

          在 php 方面,您可能需要查看 parse_str。如果您使用第二个可选参数,它将将该 url 字符串解析为变量或数组。

          【讨论】:

            【解决方案7】:

            此问题的另一个可能原因:如果您的表单没有分配任何类型的提交操作,则每当您在填写表单时按“ENTER”键时,表单将被提交到当前 URL,所以你会看到序列化的数据出现在 URL 中,就好像你在使用 GET ajax 事务一样。一个简单的解决这个问题的方法,只是阻止 ENTER 在按下时提交表单:

            //Prevent Form Submission when Pressing Enter
            $("form").bind("keypress", function(e) {
            if (e.keyCode == 13)
                return false;
            });
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-10-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-03-11
              • 2011-10-14
              相关资源
              最近更新 更多