Сериализация jquery и $ .post - PullRequest
22 голосов
/ 28 мая 2009

Я пытаюсь отправить много данных из формы, используя метод $ .post в jQuery. Сначала я использовал функцию 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;  

Ответы [ 7 ]

18 голосов
/ 16 октября 2009

Если вы используете элемент <button> для активации сериализации и ajax, и если этот элемент <button> находится внутри элемента form, button автоматически действует как отправка формы, независимо от того, что другое. щелкните назначение, которое вы дадите ему с помощью jQuery.

Тип = 'Отправить'

<button></button> и <button type='submit'></button> - это одно и то же. Они отправят форму, если они помещены в элемент <form>.

Тип = 'кнопка'

<button type='button'></button> отличается. Это обычная кнопка, которая не будет отправлять форму (если вы специально не отправите ее через JavaScript).

И в случае, когда элемент form не имеет указанного атрибута действия, эта отправка просто отправляет данные обратно на ту же страницу. Таким образом, вы увидите обновление страницы вместе с сериализованными данными, отображаемыми в URL, как если бы вы использовали GET в своем ajax.

Возможные решения

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 - Переместите элемент <button> за пределы элемента <form>. Это не позволит кнопке отправить форму.

До:

<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);
  });
});

Очевидно, что не видя весь ваш код, я понятия не имею, так ли это для вашей проблемы, но единственная причина, по которой я когда-либо видел поведение, которое вы описываете, заключается в том, что кнопка отправки была <button> без указанного типа.

7 голосов
/ 28 мая 2009

попробуйте использовать serializeArray () вместо serialize (). serialize () создаст строку запроса в кодировке URL, тогда как serializeArray () создаст структуру данных JSON.

3 голосов
/ 28 мая 2009

Что заставляет вас верить, что данные добавляются в URL?

В любом случае, не имеет ли смысла передавать значения формы в сами данные формы? Это позволит вам пропустить шаг "взорваться":

$("#addShowFormSubmit")
  .click(function() { 
      var perfTimes = $("#addShowForm").serialize(); 
      $.post("includes/add_show.php", 
         $.param({name: $("#showTitle").val()}) + "&" + perfTimes, 
         function(data) {...}); 
  });
2 голосов
/ 01 июня 2009

Так что это, вероятно, немного глупо, но я сделал функцию, которая поможет мне сделать то же самое, так как я устал каждый раз делать кучу исправлений. serializeArray отчасти раздражает, потому что он предоставляет коллекцию объектов, когда все, что я хотел, чтобы реконструировать PhP, было ассоциативным массивом. Приведенная ниже функция пройдет через сериализованный массив и создаст новый объект с соответствующими свойствами только при наличии значения.

Во-первых, функция (она принимает идентификатор рассматриваемой формы):

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 для всех моих ответов с сервера.

0 голосов
/ 18 октября 2009

Еще одна возможная причина этой проблемы: если у вас есть форма, которой не назначено какое-либо действие по отправке, всякий раз, когда вы нажимаете клавишу «ВВОД» во время заполнения формы, форма будет отправлена ​​на текущий URL, Таким образом, вы увидите, что сериализованные данные появятся в URL, как если бы вы использовали транзакцию GET ajax. Простое решение этой проблемы, просто запретите ENTER отправлять форму при ее нажатии:

//Prevent Form Submission when Pressing Enter
$("form").bind("keypress", function(e) {
if (e.keyCode == 13)
    return false;
});
0 голосов
/ 06 октября 2009

На стороне php вы можете посмотреть parse_str . Эта строка URL будет проанализирована в переменные или в массив, если вы используете второй необязательный параметр.

0 голосов
/ 03 июня 2009

Попробуйте этот синтаксис. Я использую это для сериализации формы и POST через вызов ajax к службе WCF. Кроме того, вы можете отправить это обратно в один объект 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)); 
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...