Завантаження декількох картинок або файлів на сервер з jQuery і Ajax без плагінів.

Завантаження файлів або картинок на сервер є досить типовою завданням. Але прогрес не стоїть на місці і тому зараз звичайно ж хочеться, щоб завантаження файлів відбувалася в фоновому режимі. Як правило раніше це можна було реалізувати з використанням технології flash або iframe. Також багато хто використовує плагіни такі як jQuery Form Plugin або Ajax File Upload Plugin або Multiple File Upload Plugin і море інших. З появою об'єкта FormData все стало значно простіше. FormData () дозволяє скласти набір даних для відправки на сервер за допомогою XMLHttpRequest.

Давайте ж спробуємо написати свій код без всяких плагінів (ну крім звичайно фреймворка jQuery) для завантаження картинок або файлів на сервер у фоновому режимі. Взагалі алгоритм наших дій буде приблизно такий: заповнюємо поля форми даними. Поля можуть бути якими завгодно, і текст, і текстареа і селект і файли. При виборі файлів, завдяки нашому коду на jQuery, ці файли у фоновому режимі будуть завантажені в тимчасову директорію на сервері, наприклад в "tmp". Далі при натисканні на кнопку submit форми, дані відправляються серверному скрипту, який ці дані обробить. Уявімо що це статті. Передані дані ми запишемо в базу даних з унікальним id. Далі створимо в каталозі "images" директорію c унікальним номером "id" і якщо в папці "tmp" у нас були якісь файли ми їх скопіюємо в створену папку "id" після чого очистимо папку "tmp". Резюмуючи: фоном заливаємо картинки в tmp, при Сабміт форми дані записуємо в базу, у нас появлется унікальний номер запису. Створюємо папку з цим номером і переміщаємо туди наші файли. Усе. У даній статті заливку в базу і копіювання файлів ми розглядати не будемо. Думаю тут у кожного буде щось своє. Ми зосередимося на одному - асинхронної завантаження картинок (або файлів).

Так от наш html шматок. Тут звернемо увагу на те, що у нас є гіф файл з картинкою прелоудером (зациклений гурток), який ми стилями ховаємо від показу. Також полю file дамо id = file, а формі enctype = "multipart / form-data". Ім'я поля file буде file [] тобто щоб ми могли працювати з масивом, раз у нас дозволена завантаження декількох файлів (атрибут multiple).

<! - index.php -> <meta charset = "utf-8" /> <script type = "text / javascript" src = "http://ajax.googleapis.com/ajax/libs/jquery/1 /jquery.min.js "> </ script> <style> #preloader {visibility: hidden;} </ style> <h2> Додати інформацію </ h2> <form action =" "enctype =" multipart / form-data "method =" POST "> <input type =" text "name =" name "placeholder =" Назва "/> <input type =" text "name =" description "placeholder =" Опис "/> <input id =" file "type =" file "multiple =" multiple "name =" file [] "/> <div id =" preloader "> <img alt =" loader "src =" preloader.gif "/> </ div> < div id = "info"> </ div> <! - сюди буде виводиться інформація про заливці -> <input type = "submit" name = "add" value = "Додати" /> </ form>

В даній формі у нас крім поля з файлом є ще пара полів для прикладу: input = text. Тобто перед нами звичайна форма наприклад для адмінки, яка представляє собою набір необхідних вам полів. Для початку якщо хочете можете перевірити роботу скрипта прописавши спочатку файлу рядки показу масиву FILES:

//upload.php print_r ($ _ FILES);

Тепер напишемо наш серверний скрипт, який буде викликатися за допомогою jQuery. Його завдання перекинути залиті файли з тимчасової директорії сервера в нашу, припустимо як ми вирішили в "tmp", після чого показати їх.

//upload.php function show_dir ($ dir) // функція показу картинок з tmp папки {$ list = scandir ($ dir); unset ($ list [0], $ list [1]); foreach ($ list as $ file) {echo "<img style =" height: 150px; "alt =" "src =" ./$ dir $ file "/>"; }} Foreach ($ _FILES as $ key => $ value) {// переміщення файлів в tmp move_uploaded_file ($ value [ 'tmp_name'], "tmp /".$ value [ 'name']); } Show_dir ( './ tmp /');

А тепер і наш js-скрипт, який у фоновому режимі заллє наші файли на сервер. Все чари буде виконано завдяки об'єкту FormData (). Цей код ми допишемо в кінець нашого index.php перед тегом.

<Script> $ (document) .ready (function () {$ ( '# preloader'). Hide (); $ ( '# file'). Bind ( 'change', function () {var data = new FormData ( ); var error = ''; jQuery.each ($ ( '# file') [0] .files, function (i, file) {if (file.name.length <1) {error = error + 'Файл має неправильний розмір! ';} // Перевірка на довжину імені if (file.size> 1000000) {error = error +' File '+ file.name +' is to big. ';} // Перевірка розміру файлу if (file. type! = 'image / png' && file.type! = 'image / jpg' &&! file.type! = 'image / gif' && file.type! = 'image / jpeg') {error = error + 'File '+ file.name +' doesnt match png, jpg or gif ';} // Перевірка типу файлів data.append (' file - '+ i, file);}); if (error! =' ') {$ ( '#info'). html (error);} else {$ .ajax ({url: 'upload.php', data: data, cache: false, contentType: false, processData: false, type: 'POST', beforeSend : function () {$ ( '# preloader'). show ();}, success: function (data) {$ ( '# info'). html (data ); $ ( '# Preloader'). Hide ();}});}})}); </ Script>

Ну ось начебто і все. Якщо хтось що не зрозумів, питайте. Якщо у кого то будуть доповнення, теж буду радий!
Порада: якщо ви ще не використовували код для видалення файлів з будь-якої директорії, то рекомендую для тесту поміняти функцію видалення rmdir на echo щоб переконатися що будуть видалені тільки ті файли які ви хочете видалити. Gif прелоадери можна взяти наприклад з мого уроку Як зробити Gif анімацію . Приклади в кінці статті.

Якщо кому захочеться додати краси, наприклад прогрес бар, то для цього нам треба буде дописати кілька рядків коду. В html шаблон ми додамо супер елемент з html5 - progress, а в js код, додамо кілька рядків з об'єктом XMLHttpRequest.
І так, наш html доповниться такими:

<Progress> </ progress>

А в код js допишемо:

function progressHandlingFunction (e) {if (e.lengthComputable) {$ ( 'progress'). attr ({value: e.loaded, max: e.total}); }}

і

xhr: function () {var myXhr = $ .ajaxSettings.xhr (); if (myXhr.upload) {// перевірка що здійснюється upload myXhr.upload.addEventListener ( 'progress', progressHandlingFunction, false); // передача в функцію значень} return myXhr; }

Фінальний результат js коду:

<Script> $ (document) .ready (function () {function progressHandlingFunction (e) {if (e.lengthComputable) {$ ( 'progress'). Attr ({value: e.loaded, max: e.total}) ;}} $ ( '# preloader'). hide (); $ ( '# file'). bind ( 'change', function () {var data = new FormData (); var error = ''; jQuery.each ($ ( '# file') [0] .files, function (i, file) {if (file.name.length <1) {error = error + 'Файл має неправильний розмір!';} if (file.size > 1000000) {error = error + 'File' + file.name + 'is to big.';} if (file.type! = 'image / png' && file.type! = 'image / jpg' &&! file .type! = 'image / gif' && file.type! = 'image / jpeg') {error = error + 'File' + file.name + 'doesnt match png, jpg or gif';} data.append ( ' file - '+ i, file);}); if (error! =' ') {$ (' # info '). html (error);} else {$ .ajax ({url:' productUploadImg.php ', type: 'POST', xhr: function () {var myXhr = $ .ajaxSettings.xhr (); if (myXhr.upload) {// перевірка що здійснюється upload myXhr.upload.addEventListener ( 'progr ess ', progressHandlingFunction, false); // передача в функцію значень} return myXhr; }, Data: data, cache: false, contentType: false, processData: false, beforeSend: function () {$ ( '# preloader'). Show (); }, Success: function (data) {$ ( '# info'). Html (data); $ ( '# Preloader'). Hide (); }, Error: errorHandler = function () {$ ( '# info'). Html ( 'Помилка завантаження файлів'); }}); }})}); </ Script>

UPD2: Для тих хто хоче оформити прогрес бар більш красиво, може подивитися статтю з оформлення елемента прогрес на css , А в цій статті можна подивитися на надихаючі приклади зовнішнього вигляду прогрес бару .

Дополнительная информация

rss
Карта