Задать вопрос

Как отправить с помощью jquery ajax файл вместе с данными формы?

И снова приветствую вас друзья! И опять запарка с jquery. Есть форма для добавления некоторых данных и файла. Плагин для добавления файла взял вот у этого товарища, демка там-же:

https://github.com/danielm/uploader

Это всё что нужно и этого хватит вполне. Знаю что есть круче, но с ним разберусь как будет время, слишком много там всего:

https://blueimp.github.io/jQuery-File-Upload/

Вобщем взял я первый вариант, отладочная консоль мне понравилась очень к тому же.
Переделал немного демку под себя, перевел все на русский язык. А задача следующая:

Данные из формы пойдут на добавление в базу данных вместе с ссылкой на изображение. Имя файла изображения будет составлено из данных этой формы. Вот только не получается у меня отправить всё это одним запросом, если это и возможно, то у меня недостаточно знаний по jquery и ajax.

Я стал сооружать велосипед.

$(".cloth_add").submit(function() {
    $.ajax({
        type: "POST",
        url: "upload.php",
        data: $(".cloth_add").serialize(),
        cache: true,
        success:
            function processData(data) {
            fileUpload('#cloth-upload', 'upload.php', 1, data);
            alert(data);
        }
    });
    return false;
});


Тут он отправляет данные из формы в обработчик файла, оттуда возвращает скомбинированное из пост POST имя файла, и передает параметром в функцию. Первый параметр - блок div, второй обработчик, третий количество допустимых файлов и последний имя файла, которое будет представлять самый первый ключ массива $_FILES. Эти параметры уже передаются в функцию, которая обращается к самому плагину, выглядит так:

function fileUpload (block, handler, numberOfFiles, filename) {
$(document).ready(function() {
    $(block).dmUploader({
        url: handler,
        maxFiles: numberOfFiles,
        fileName: filename,
        dataType: 'html',
        allowedTypes: 'image/*',
        onInit: function(){
            $.fileUpload.addLog('#upload-debug', 'default', 'Готов к загрузке');
        },
        onBeforeUpload: function(id){
            $.fileUpload.addLog('#upload-debug', 'default', 'Началась загрузка файла #' + id);

            $.fileUpload.updateFileStatus(id, 'default', 'Загрузка...');
        },
        onNewFile: function(id, file){
            $.fileUpload.addFile('#upload-files', id, file);

            /*** Begins Image preview loader ***/
            if (typeof FileReader !== "undefined"){

                var reader = new FileReader();

                // Last image added
                var img = $('#upload-files').find('.upload-image-preview').eq(0);

                reader.onload = function (e) {
                    img.attr('src', e.target.result);
                }

                reader.readAsDataURL(file);

            } else {
                // Hide/Remove all Images if FileReader isn't supported
                $('#upload-files').find('.upload-image-preview').remove();
            }
            /*** Ends Image preview loader ***/

        },
        onComplete: function(){
            $.fileUpload.addLog('#upload-debug', 'default', 'Все загрузки завершены');
        },
        onUploadProgress: function(id, percent){
            var percentStr = percent + '%';

            $.fileUpload.updateFileProgress(id, percentStr);
        },
        onUploadSuccess: function(id, data){
            $.fileUpload.addLog('#upload-debug', 'success', 'Загрузка файла #' + id + ' завершена');

            $.fileUpload.addLog('#upload-debug', 'info', 'Получен ответ от сервера для файла #' + id + ': ' + JSON.stringify(data));

            $.fileUpload.updateFileStatus(id, 'success', 'Загрузка завершена');

            $.fileUpload.updateFileProgress(id, '100%');
        },
        onUploadError: function(id, message){
            $.fileUpload.updateFileStatus(id, 'error', message);

            $.fileUpload.addLog('#upload-debug', 'error', 'Не удалось загрузить файл #' + id + ': ' + message);
        },
        onFileTypeError: function(file){
            $.fileUpload.addLog('#upload-debug', 'error', 'File \'' + file.name + '\' Файл не является изображением и не может быть добавлен');
        },
        onFileSizeError: function(file){
            $.fileUpload.addLog('#upload-debug', 'error', 'File \'' + file.name + '\' Файл не может быть добавлен так как превышен допустимый размер');
        },
        onFallbackMode: function(message){
            $.fileUpload.addLog('#upload-debug', 'info', 'Браузер не поддерживается(попробуйте сделать следующее!): ' + message);
        }
    });
});
}


Сам плагин не влез, но он не большой, ссылке на гитхаб можно посмотреть:

https://github.com/danielm/uploader/blob/master/sr...

Там всё отправляется этим запросом:
// Ajax Submit
        $.ajax({
            url: widget.settings.url,
            type: widget.settings.method,
            dataType: widget.settings.dataType,
            data: fd,
            cache: false,
            contentType: false,
            processData: false,
            forceSync: false,
            xhr: function(){
                var xhrobj = $.ajaxSettings.xhr();
                if(xhrobj.upload){
                    xhrobj.upload.addEventListener('progress', function(event) {
                        var percent = 0;
                        var position = event.loaded || event.position;
                        var total = event.total || e.totalSize;
                        if(event.lengthComputable){
                            percent = Math.ceil(position / total * 100);
                        }

                        widget.settings.onUploadProgress.call(widget.element, widget.queuePos, percent);
                    }, false);
                }

                return xhrobj;
            },
            success: function (data, message, xhr){
                widget.settings.onUploadSuccess.call(widget.element, widget.queuePos, data);
            },
            error: function (xhr, status, errMsg){
                widget.settings.onUploadError.call(widget.element, widget.queuePos, errMsg);
            },
            complete: function(xhr, textStatus){
                widget.processQueue();
            }
        });
    };

    $.fn.dmUploader = function(options){
        return this.each(function(){
            if(!$.data(this, pluginName)){
                $.data(this, pluginName, new DmUploader(this, options));
            }
        });
    };


Дело то вот в чём: наверняка же можно всё вместе отправить - и файл и форму одним запросом, не сооружая велосипедов. Форма сама по себе не большая, можно просто вернуть ключ массива и вот тебе имя нового файла! А надо будет потом разобрать по частям большую форму, и тут уже это не прокатит. Уважаемые знатоки ява скрипта! Помогите пожалуйста модифицировать этот плагин, чтобы отправить всё одним запросом. Ну или двумя, но чтобы данные приходили одновременно, т.к. первые отправленные данные POST к тому моменту как придет файл на сервер уже не существуют.
  • Вопрос задан
  • 3094 просмотра
Подписаться 3 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 1
@J01 Автор вопроса
Кое с чем разобрался, есть там такая опция:

extraData: {
  varName:1,
  varName:'string'
}


в принципе в неё можно добавить сколь угодно ключей и значений и она как раз попадает в массив $_POST. Так что всё таки разработчик предусмотрел такую возможность.

Только вот дело в том, что varName это ключ, а 'string' значение, значит в пост попадает массив, внутри которого уже данные, полученные из формы. Получается что они были предназначены для отправки постом и подготовлены для этого, а попав в другой массив, амперсанд уже теряет смысл. Данные я так понял это добавляется здесь:

// Append extra Form Data
    $.each(widget.settings.extraData, function(exKey, exVal){
      fd.append(exKey, exVal);
    });


fd это formData
Может кто-нибудь знает как сделать, чтобы данные из формы добавлялись сюда в чистом виде?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы