Svetlika (svetlika) wrote,
Svetlika
svetlika

Category:

Отправка форм и файлов ajax-ом или jQuery, jQuery.Form и IE8

Чисто программисткий пост, но не могу не удержаться, вдруг кому-то кроме меня из веб-разработчиков окажется полезным.

Для одного проекта решила придерживаться такой (довольно распространенной, надо заметить) схемы отправки (обработки) форм.
Есть страница, на ней есть форма. На сервер форма отправляется ajax-ом, с помощью небезысвестного jquery.form. На сервере проверяются отправленные данные и возвращается на страницу (без перезагрузки) некий ответ - либо все ок, запись сохранена (и далее следует редирект куда-нибудь, куда сервер же покажет), либо выводится сообщение о некорректных данных.

Плюс данного подхода - не надо перегружать страницу, и введенные пользователем данные никуда не пропадают (не надо их обратно странице передавать, выводить в форму), в общем - удобно, и пользователю в случае ввода некорретных данных достаточно подправить только те данные, которые не удовлетворили сервер.
Одна важная деталь: ответ сервер возвращал в JSON.

Пока вся разработка велась под Firefox 3.6, все было просто прекрасно - данные отправлялись, редиректы редиректились, количество форм на такой связке росло и увеличивалось, и тут... и тут заказчик уточнил, что ему очень надо, чтобы данный проект работал в IE8.
А как раз-таки в IE8 от этой связки работала ровно половина. Данные отправлялись, а вот сообщений от сервера не выводилось и, соответственно, редиректы не производились.



Пичалька... подумала я и стала пытаться заставить эту штуку работать в IE8.

Решение 1, которое удовлетворит тех, кому не надо вместе с текстовыми полями формы грузить на сервер еще и файлы.
Ради интереса, убрала из атрибутов формы enctype='multipart/form-data'
И, о чудо - IE8 получил ответ от сервера, стал выводить сообщения об ошибках и делать редиректы.
Но мне-то нужно еще и файл залить на сервер. Через эту же форму. Вместе с текстовыми полями формы...

Решение 2, для тех, кому надо все-таки еще и файлы на сервер загружать вместе с данными формы.
Путем долгих странных шаманских танцев вокруг IE8, своих js-скриптов, ковыряния в jquery.form я выяснила, что по какой-то неведомой причине jquery.form именно в IE8 (в IE9 такой проблемы не было) не вызывает мою функцию-обработчик, повешенную на его свойство "success".
С помощью такой-то матери, интуиции и alert-ов я нашла место в jquery.form, где это все ломалось, и до вызова функции-обработчика на success, оказывается, jquery.form просто не доходил.
А ломалось оно в этом месте:

var parseJSON = $.parseJSON || function(s) {
return window['eval']('(' + s + ')');
};

Или, если быть точной, то при вызове сей чудесной функции:

data = parseJSON(data);

Впрочем, если явно не указывать jquery.form тип возвращаемого значения и пытаться распарсить полученный json от сервера уже в самой функции-обработчике success, куда в таком случае управление передавалось, то ээ... парсится данный ответ сервера в IE8 как json отказывался и выдавал ошибку. Я перепробовала все возможные способы, которые мне попались на просторах интернета, а именно:

data = $.parseJSON(data1);
data = jQuery.parseJSON(data1);
data = eval(data1);
data = eval('(' + data1 + ')');

и даже попытка получить ответ сервера, чтобы проверить его валидатором json

promt('data1',data1);

вызвала неудачу.

Так же, по совету некоторых заменила doctype на тот, который советовали:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

Но и это не помогло...

IE8 упорно отказывался признавать ответ сервера за JSON, а так же признаваться в умении парсить этот самый JSON с помощью jquery.

В общем, мне порядком надоели все эти танцы вокруг jquery, jquery.form, IE8 и JSON и я решила воспользоваться старым способом распарсить JSON, которым пользовалась до плотной работы с jquery.
То есть, я пошла и скачала вот эту замечательную функцию: json_parse, подключила этот скрипт на страницу, и заменила в jquery.form вызов его собственной parseJSON на json_parse.

И, о чудо! IE8 перестал капризничать, JSON стал парситься, функция-обработчик success запускаться, выводить сообщения и делать редиректы.
Файлы грузятся, данные сохраняются, и все это работает в IE8, Firefox 3.6, Chrome.
При этом jquery.form я указываю явно тип данных - json, т.е. прикручивается он у меня к форме вот с такими параметрами:

            var options1 = {
                dataType: "json", //это важно, потому что иначе в IE8 в функцию обработки
   //попадал действительно не очень валидный ответ, с каким-то </P>
//приписанным в конце к ответу, а тип указать - то ответ приходил чистенький
iframe: true, //поставила на всякий случай, все равно jquery.form при отправке
//файла юзает iframe, так пусть уж делает это явно и всегда
                beforeSubmit: function(arr, $form, options) { 
//тут я очищаю на всякий случай сообщения об ошибках перед
//перед отправкой и показываю гифку, что происходит некий процесс
                                return true;                                
                            },
                  success: showResponse

            };
function showResponse(data1) {
// а это функция-обработчик, которая пользуется полученным уже распарсенным data1
// выводит сообщения об ошибках и запускает редиректы
}


Минус данного подхода очевиден: дополнительная библиотека, плюс пришлось залезть и поправить вызов в jquery.form, чтобы все это работало.
Впрочем, особо желающие, если это кому-то понадобится, могут внести тело функции json_parse внутрь jquery.form и пользоваться модифицированным плагином.

Технические данные: использовалась jquery 1.6.2, потом была заменена на 1.7.1, что не спасло IE8.
jquery.form был последний отсюда: http://malsup.com/jquery/form/



Tags: ajax, jquery, js, web, work
Subscribe

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 8 comments