Инструменты пользователя

Инструменты сайта


development:ajax-files:swfuload

SWFUpload. AJAX загрузка файлов на сервер

Введение

Асинхронные запросы в web-разработке не редкость. Принцип очень прост:

  1. Формируем в JavaScript необходимые данные.
  2. Оправляем на сервер.
  3. Получаем ответ и перестраиваем страницу опять же с помощью JavaScript.

Но все меняется когда мы начинаем говорить о AJAX передаче данных.

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

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

Однако у многих есть два существенных ограничения (сугубо по моему личному мнению):

  • Загрузка только одного файла. Сюда же отнесем загрузчики, которые передает на сервер несколько файлов, но открывают по одному за раз. Другими словами для загрузки 10 файлов, приходится 10 раз открывать форму выбора файла.
  • Стандартный внешний вид загрузчика и вид отображения загрузки файлов. Такой загрузчик не всегда можно встроить в дизайн сайта.

Пример загрузки SWFUpload Вся прелесть SWFUpload заключается в том, что он позволяет выбирать и загружать сразу несколько файлов, а внешним видом flash является только одна картинка кнопки загрузки. При этом flash передает всю информацию о загружаемых файлах в JavaScript, на основании, которой можно построить абсолютно любое отображение процесса загрузки файлов.

И еще одна маленький бонус - можно настроить фильтрацию файлов по типам и размеру еще до отправки файлов на сервер.


О SWFUpload

Сайт разработчиков: swfupload.org
Полная документация: swfupload documentation

Для работы с загрузчиком необходимо по крайней мере следующие файлы:

  • swfupload.js - собственно сама библиотека.
  • swfupload.swf - flash-загрузчик.
  • swfupload_handlers.js - скрипты обработчиков событий (этот файл мы создадим сами).
  • ajax.php - обработчик файлов на стороне сервера (его мы тоже напишем сами).
  • button_sprite.png - картинка кнопки (четыре кадра).

Инициализация

Для инициализации загрузчика необходимо подключить библиотеку swfupload.js и разместить следующий код:

JavaScript:
 
var loader = new SWFUpload({
  button_placeholder_id: "loader" 
});
HTML:
 
<div id="loader"></div>

Настройка

Настройка загрузчика происходит путем передачи объекта с параметрами при инициализации (комплексная настройка) или путем задания отдельных параметров, используя методы самого SWFUpload (эти методы здесь рассмотрены не будут, поэтому при необходимости, обратитесь к документации).

Рассмотрим наиболее часто-используемые параметры, разбив их по смысловым группам.

Общие параметры

  • debug - включает окно отладчика, в котором отображаются все текущие настройки загрузчика и все изменения его состояния.
  • upload_url - путь до обработчика на сервере.
  • flash_url - путь до flesh загрузчика.

Пример:

JavaScript:
 
var loader = new SWFUpload({
  debug: true,
  upload_url: "/ajax.php", 
  flash_url: "/swfupload.swf"
});

Параметры внешнего вида

Как я уже отмечал, внешний вид flesh загрузчика представляет собой картинку. Единственная особенность этой картинки в том, что она состоит из четырех кадров, отображающих различные состояния кнопки (обычное, наведение курсора, нажатие мыши и еще какое-то :-)).

  • button_placeholder_id - идентификатор HTML-элемента, который будет выступать загрузчиком (пожалуй единственный обязательный параметр).
  • button_image_url - путь до картинки кнопки.
  • button_width - ширина картинки.
  • button_height - высота одного кадра картинки.
  • button_text - текст на кнопке.

Пример:

JavaScript:
 
var loader = new SWFUpload({
  button_placeholder_id: "loader",
  button_image_url: "/button_sprite.png",
  button_width: 60,
  button_height: 23,
  button_text: "<b>Click</b> <span class='redText'>here</span>"
});

Параметры загружаемых файлов

  • file_post_name - ключ в массиве $_FILES по которому будут передаваться файлы на сервер.
  • file_types - список допустимых типов файлов для загрузке.
  • file_types_description - описание типов файлов.
  • file_size_limit - максимальный размер загружаемого файла.

Пример:

JavaScript:
 
var loader = new SWFUpload({
  file_post_name: "filedata",
  file_types: "*.jpg;*.gif;*.png",
  file_types_description: "Фотографии",
  file_size_limit: "2 MB"
});

Параметры обработчиков событий

Параметры обработчиков по своей сути являются именами функций, которые должны будут обрабатывать эти события.

  • file_queued_handler - задет обработчик события «файл поставлен в очередь закачки».
  • file_queue_error_handler - задет обработчик события «ошибка постановки файла в очередь».
  • file_dialog_complete_handler - задет обработчик события «диалоговое окно выбора файла закрыто и файлы поставлены в очередь».
  • upload_start_handler - задет обработчик события «загрузка началась».
  • upload_progress_handler - задет обработчик события «процесс загрузки».
  • upload_error_handler - задет обработчик события «ошибка при загрузке».
  • upload_success_handler - задет обработчик события «файл загружен».
  • upload_complete_handler - задет обработчик события «загрузка завершена». Вызывается сразу после события «файл загружен» или «ошибка при загрузке».

Пример:

JavaScript:
 
var loader = new SWFUpload({
  file_queued_handler: myFileQueuedFunction,
  file_queue_error_handler: myFileQueueErrorFunction,
  file_dialog_complete_handler: myFileDialogCompleteFunction,
  upload_start_handler: myUploadStartFunction,
  upload_progress_handler: myUploadProgressFunction,
  upload_error_handler: myUploadErrorFunction,
  upload_success_handler: myUploadSuccessFunction,
  upload_complete_handler: myUploadCompleteFunction
});

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

Подробное описание представленных обработчиков находится в разделе События.

Хотя это и не обязательно, но практика показала, что лучше определять все обработчики событий связанных с загрузкой.

Пользовательские параметры

При желании, можно задать какие-либо свои параметры. Параметры передаются обычным объектом, содержащим наборы ключ:значение.

Пример:

JavaScript:
 
var loader = new SWFUpload({
  custom_settings: {
    my_setting_1: "my_value_1",
    my_setting_2: "my_value_2",
    my_setting_3: "my_value_3"
  }
});

Здесь приведен частичный список параметров, за полным перечнем параметров обратитесь к официальной документации.


Методы

Здесь мы рассмотрим лишь малую часть методов SWFUpload. По большому счету для большинства приложений достаточно использовать всего лишь два метода (оба метода приведены в примерах обработчиков событий).

startUpload(file_id)

Запускает загрузку файла.

Входные параметры:

  • file_id - идентификатор файла. Если параметр не задан, то загружается первый в очереди файл.

Выходные параметры:

Не возвращает данных.

cancelUpload(file_id, trigger_error_event)

Отменяет загрузку файла и убирает его из очереди.

Входные параметры:

  • file_id - идентификатор файла. Если параметр не задан, то отменяется загрузка первого в очереди файла.
  • trigger_error_event - необязательный параметр, если задан как false, то событие uploadError подавляется.

Выходные параметры:

Не возвращает данных.

stopUpload()

Останавливает текущую загрузку файла и заново помещает его в очередь.

Входные параметры:

Нет входных параметров.

Выходные параметры:

Не возвращает данных.

getStats()

Возвращает статистические данные.

Входные параметры:

Нет входных параметров.

Выходные параметры:

  • object.in_progress - число, 1 или 0, показывающее идет ли сейчас загрузка файлов.
  • object.files_queued - число файлов в очереди.
  • object.successful_uploads - число успешно загруженных файлов.
  • object.upload_errors - число ошибок при загрузке файлов.
  • object.upload_cancelled - число отмененных файлов.
  • object.queue_errors - число ошибок при постановке файлов в очередь загрузки.

getFile(file_id|index)

Возвращает данные о файле.

Входные параметры:

  • file_id|index - идентификатор файла или его индекс.

Выходные параметры:

  • object.id- строка, идентификатор файла.
  • object.index - число, индекс файла.
  • object.name - строка, имя файла.
  • object.size - число, размер файла в байтах.
  • object.type - строка, тип файла.
  • object.creationdate - дата, дата создания файла.
  • object.modificationdate - дата, дата последнего изменения файла.
  • object.filestatus - число, код статус файла. Коды статусов находятся в константах SWFUpload.FILE_STATUS.

События

При каждом изменении состояния flesh генерирует соответствующее событие. Именно создание своих обработчиков этих событий и делает SWFUpload невероятно гибким инструментом.

И так чтобы показать все картину целиком я покажу в каком порядке появляются события.

  • flashReady() - единственное событие которое нельзя переопределить - flash сообщает библиотеке, что она готова принимать комманды.
  • swfUploadLoaded() - вызывается сразу после события flashReady() и сообщает, что можно использовать методы SWFUpload.
  • fileDialogStart() - возникает перед отображением диалогового окна загрузки файлов.
  • fileQueued() - возникает при удачной постановке файла в очередь загрузки.
  • fileQueueError() - возникает при ошибке в процессе постановки файла в очередь загрузки.
  • fileDialogComplete() - возникает сразу после закрытия диалогового окна загрузки файлов и обработки файлов (постановки в очередь загрузки).
  • uploadStart() - возникает непосредственно перед загрузкой файла.
  • uploadProgress() - периодически возникает в процессе загрузки файла.
  • uploadError() - возникает в случаи ошибки загрузки файла.
  • uploadSuccess() - возникает после удачной загрузки файла.
  • uploadComplete() - всегда возникает в конце цикла загрузки файла, не зависимо от исхода.
  • debug() - возникает при любом изменении состояния, если задан параметр debug.

Давайте рассмотрим обработчики основных событий.

fileQueued

Событие fileQueued возникает при удачной постановке файла в очередь загрузки.

Событие передает обработчику следующую информацию:

  • file_object - информация о файле в виде объекта.

Пример:

JavaScript:
 
function myFileQueuedFunction(file) {
  try {
    //вывод данных о файле на страницу
    //к примеру, создаем элемент <p> содержащий имя файла и добавляем его в <div id="filelist">
    var filelist = document.getElementById('filelist');
    var p = document.createElement('P');
    p.innerHTML = file.name;
    filelist .appendChild(p);
  } catch (ex) {
    //обрабатываем ошибку
    //к примеру, выводим в debug
    this.debug(ex);
  }
};

fileQueueError

Событие fileQueueError возникает при появлении ошибки в процессе постановки файла в очередь загрузки.

Событие передает обработчику следующую информацию:

  • file_object - информация о файле в виде объекта.
  • error_code - код ошибки.
  • message - текстовое описание ошибки.

Советую ориентироваться на код ошибки, а не на текст. Коды ошибок находятся в константах SWFUpload.QUEUE_ERROR.

Пример:

JavaScript:
 
function myFileQueueErrorFunction(file, code, message) {
  try {
    //вывод ошибки на страницу
    //к примеру, создаем элемент <p> содержащий имя файла и текст ошибки и добавляем его в <div id="filelist">
    var filelist = document.getElementById('filelist');
    var p = document.createElement('P');
    var error;
    switch(code) {
      case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: error = 'Превышен допустимый размер файла'; break;
      case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: error = 'Пустой файл'; break;
      case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: error = 'Недопустимое расширение файла'; break;
      case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED: error = 'Превышен установленный предел количества загрузок'; break;
      default: error = 'Неизвестная ошибка'; break;
    }
    p.innerHTML = file.name + ' - ' + error;
    filelist .appendChild(p);
  } catch (ex) { 
    //обрабатываем ошибку
    //к примеру, выводим в debug
    this.debug(ex);
  }
};

fileDialogComplete

Событие fileDialogComplete возникает после закрытия и постановки файлов в очередь.

Событие передает обработчику следующую информацию:

  • number_of_files_selected - количество выбранных файлов в текущей загрузке.
  • number_of_files_queued - количество файлов поставленных в очередь в текущей загрузке.
  • total_number_of_files_in_the_queued - общее количество поставленных файлов в очередь (можно запускать несколько загрузок подряд).

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

Пример:

JavaScript:
 
function myFileDialogCompleteFunction(selected, queued, queued_total) {
  try {
    //к примеру, запускаем загрузку файлов
    this.startUpload();
  } catch (ex) {
    //обрабатываем ошибку
    //к примеру, выводим в debug
    this.debug(ex);
  }
};

uploadStart

Событие возникает непосредственно перед загрузкой файла.

Событие передает обработчику следующую информацию:

  • file_object - информация о файле в виде объекта.

Пример:

JavaScript:
 
function myUploadStartFunction(file) {
  try {
    //вывод данных о файле на страницу
    //к примеру, выводим размер файла и статус "Загружается" в <div id="filestatus">
    var status = document.getElementById('filestatus');
    status.innerHTML = "Размер файла: " + file.size + " байт. Загружается...";
 
  } catch (ex) {
    //обрабатываем ошибку
    //к примеру, выводим в debug
    this.debug(ex);
  }
};

uploadProgress

Событие периодически возникает в процессе загрузки файла.

Событие передает обработчику следующую информацию:

  • file_object - информация о файле в виде объекта.
  • bytes_complete - байт загружено.
  • total_bytes - байт всего.

Пример:

JavaScript:
 
function myUploadProgressFunction(file, loaded, total) {
  try {
    //вывод данных о прогрессе загрузке файла
    //к примеру, выводим процент загрузки в <div id="fileprogress">
    var progress = document.getElementById('fileprogress');
    var percent = Math.round(100 * loaded / total);
    progress.innerHTML = "Загружено: " + percent + "%";
 
  } catch (ex) {
    //обрабатываем ошибку
    //к примеру, выводим в debug
    this.debug(ex);
  }
};

uploadError

Событие uploadError возникает при появлении ошибки в процессе загрузки файлов.

Событие передает обработчику следующую информацию:

  • file_object - информация о файле в виде объекта.
  • error_code - код ошибки.
  • message - текстовое описание ошибки.

Советую ориентироваться на код ошибки, а не на текст. Коды ошибок находятся в константах SWFUpload.UPLOAD_ERROR.

Пример:

JavaScript:
 
function myUploadErrorFunction(file, code, message) {
  try {
    //вывод ошибки на страницу
    //к примеру, выводим текст ошибки в <div id="filestatus">
    var status = document.getElementById('filestatus');
    status.innerHTML = "Ошибка: " + message;
  } catch (ex) { 
    //обрабатываем ошибку
    //к примеру, выводим в debug
    this.debug(ex);
  }
};

uploadSuccess

Событие uploadSuccess возникает при удачной загрузке файла

Событие передает обработчику следующую информацию:

  • file_object - информация о файле в виде объекта.
  • server_data - содержит ответ сервера.
  • received_response - признак получения ответа.

Если по каким-либо причинам после удачной загрузки файла не вызвано событие uploadSuccess, то через определенное время (assume_success_timeout) событие все равно будет вызвано, при этом received_response будет содержать false.

Пример:

JavaScript:
 
function myUploadSuccessFunction(file, serverData, rr) {
  try {
    //вывод сообщения о загрузке файла
    //к примеру, выводим сообщения в <div id="filestatus">
    var status = document.getElementById('filestatus');
    status.innerHTML = "Файл " + file.name + " загружен.";
 
  } catch (ex) {
    //обрабатываем ошибку
    //к примеру, выводим в debug
    this.debug(ex);
  }
};

uploadComplete

Событие всегда возникает в конце цикла загрузки файла, сразу после uploadSuccess или uploadError.

Событие передает обработчику следующую информацию:

  • file_object - информация о файле в виде объекта.

Вызов события показывает, что цикл загрузки файла завершен. Это отличное место для автоматического запуска загрузки следующего файла.

Пример:

JavaScript:
 
function myUploadCompleteFunction(file) {
  try {
    //вывод сообщения о загрузке файла
    //к примеру, проверяем есть ли еще файлы в очереди и запускаем их загрузку
    if (this.getStats().files_queued != 0) {
      this.startUpload();
    }
  } catch (ex) {
    //обрабатываем ошибку
    //к примеру, выводим в debug
    this.debug(ex);
  }
};

Резюме

SWFUplaod очень гибкий инструмент для AJAX-загрузки файлов, но при этом требует более глубоких знаний в области программирования.

Я рассказал лишь о части методов и привел простенькие примеры обработчиков событий, но надеюсь что этот материал поможет вам сэкономить время на начальном этапе изучения SWFUpload.

Полное описание всех настроек, методов и событий представлено в официальной документации на сайте разработчика.

development/ajax-files/swfuload.txt · Последнее изменение: 2015.09.19 05:29 — 127.0.0.1