Создание jQuery плагина для массовой загрузки файлов на сервер

С появлением HTML5 File API загрузка файлов на сервер перестала быть проблемой. Раньше для этого использовались костыли, использующие Silverlight или Flash. Теперь же мы можем использовать только java script. Для загрузки файлов на сервер появились 2 новых объекта FormData и FileReader из XMLHttpRequest 2 и File API соответственно. В своем примере я использую FormData т.к. работа с ним мне показалась удобнее. Цель задачи состоит в том, чтобы при нажатии на кнопку типа file можно было выбрать сразу несколько (либо одну) фотографий и сразу же отправить их на сервер, используя при этом все плюшки которые нам дает jQuery.

Для начала я приведу пример «пустого » jQuery плагина:

[codesyntax lang=»javascript» title=»JS»]

// Utility for object create
if ( typeof Object.create !== 'function' ) {
	Object.create = function( obj ) {
		function F() {}
		F.prototype = obj;
		return new F();
	};
}

(function( $, window, document, undefined ) {
	var FileUploader = {
		init: function( options, elem ) {}
	};

	$.fn.FileUploader = function( options ) {
		return this.each(function() {
			var fileuploader = Object.create( FileUploader );
            fileuploader.init( options, this );
		});
	};

	$.fn.FileUploader.options = {};

})( jQuery, window, document );

[/codesyntax]

 

Параметры анонимной функции нужны для кеширования объектов и безопасности (если вдруг кто-то решит переопределить undefined).

Далее нам нужно создать 3 метода, которые будут осуществлять необходимый функционал.

1. init

Здесь мы инициализируем свойства нашего объекта, сохраняем пользовательские настройки и вешаем событие на нашу кнопку.

[codesyntax lang=»javascript» title=»JS»]

init: function( options, elem ) {
	var self = this;
	self.elem = elem;
	self.$elem = $( elem );
	self.options = $.extend( {}, $.fn.FileUploader.options, options );
	self.$elem.on('change', function(){self.filesUpload()});
}

[/codesyntax]

2. filesUpload

Метод отвечает за перебор всех выбранных файлов, выполнение действий перед загрузкой на сервер (ф-ция beforeUpload) и собсвенно вызова функции для загрузки каждого файла

[codesyntax lang=»javascript» title=»JS»]

filesUpload: function(){
    var self = this;
    for(var i=0;i<self.elem.files.length; i++){
        self.options.beforeUpload(self.elem.files[i]);
        self.fileUpload(self.elem.files[i]);
    }
}

[/codesyntax]

3. fileUpload

Самое интересное! Загрузка файла на сервер с помощью FormData$.ajax и настроек для window.XMLHttpRequest(). 

[codesyntax lang=»javascript» title=»JS»]

fileUpload: function(file){
    var self = this,
        form = new FormData();
    form.append('path', '/');
    form.append('file[]', file);
    $.ajax({
        xhr: function(){
            var xhr = new window.XMLHttpRequest();
            // Upload progress
            xhr.upload.addEventListener('progress', function (e) {
                if (e.lengthComputable) {
                    self.options.progress(e.loaded, e.total);
                }
            }, false);
            return xhr;
        },
        type: 'POST',
        url: self.options.uploadURL,
        data: form,
        cache: false,
        contentType: false,
        processData: false,
        success: function(data){
            self.options.afterUpload(data);
        },
        dataType: self.options.dataType,
        error: function(jqXHR, textStatus, errorThrown){
            self.options.error(jqXHR, textStatus, errorThrown);
        }
   })
}

[/codesyntax]

Весь плагин можно посмотреть здесь. Код не претендует на идеальность. Буду рад, если кто-то дополнит или поправит.

Запись опубликована в рубрике JavaScript/JQuery с метками , . Добавьте в закладки постоянную ссылку.

2 комментария: Создание jQuery плагина для массовой загрузки файлов на сервер

  1. Насколько мне известно, все эти костыли-«загрузки файлов» на html5, JQuery и прочем, не способны пережать фотки ДО отправки на сервер, в отличие от Flash. Таким образом, ваши 100 фотографий с вечеринки или поездки, занимающие 2 гига места могут быть загружены на сервер весьма за небыстро, особенно если у вас мобильный инет или ADSL или зарезанный бесплатный WI-FI в кафе. А после пережатия для web, эти же фотки заняли бы в 10-20 раз меньший размер и легко бы отправились. Я понимаю, что поиграться с HTML5 — приятно, но практического применения это не имеет.

    • Ну лично мне кажется костылем как раз применение флеша для загрузки файлов на сервер. Я бы использовал его только для поддержки старых браузеров. Сжатие картинок на клиенте это конечно хорошо, но во первых речь идет не только о картинках, а во вторых часто бывает нужно хранить на сервере оригиналы.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *