Динамическая загрузка файлов на jQuery. Ajax и PHP. Загрузка изображения на сервер

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

Там на сайте всё расписано очень хорошо, плюс сам плагин достаточно простой, однако, всё-таки поясню всё на примере. Для начала привожу простой код HTML-страницы :








Загрузка файлов






$(function() {
$("#file_upload").uploadify({
"formData" : {
"timestamp" : "",
"token" : ""
},
"uploader" : "uploadify.php"
});
});


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

Так же подключается jQuery и сам плагин. Дальше создаётся форма, а у input с type="file" ставится id , который затем уже будет использоваться в скрипте.

В самом скрипте передаются данные в formData . А именно текущее время и секретный токен . Вместо "unique_salt " может быть любая секретная строка. В свойстве "uploader " передаётся скрипт-обработчик. Теперь сам код этого обработчика:

Код я прокомментировал, поэтому, думаю, что в нём разобраться не составит труда. Единственное, что отмечу - проверок здесь недостаточно. Впрочем, про я писал в отдельной статье.

ProgressBar в этот плагин так же встроен, так что всё уже сделали за нас. В этом и состоит преимущество библиотеки jQuery и плагинов для неё. Очень сложные задачи, такие как динамическая загрузка файлов на сервер с ProgressBar , которые потребуют весь день на разработку, а потом ещё несколько дней на исправление ошибок, решаются за несколько минут с помощью готовых плагинов.

Наверное многие сталкивались с вопросом "Как загрузить файл на сервер с помощью JS и JQuery?".
И вероятно не у всех получилось это сделать. На самом деле все не так сложно как кажется.
В данном уроке я опишу процесс загрузки файла на сервер(хостинг) .
Для обмена данными между браузером и веб-сервером, используется технология ajax.
Версия JQuery используемая в рецепте: 2.2.2.

Создаем примитивную разметку из тегов html, head и body.
В теге head необходимо прописать путь до библиотеки jquery.
В примере я использую jquery с сервера google.

В теге body создаем форму, которая состоит из тега input и button.
С помощью input type="file" осуществляется выбор файла для загрузки.
Тег button необходим для запуска js кода на передачу файла.

Форме задаем name="uploader", enctype="multipart/form-data", method="POST".
Имя формы: name="uploader"
Способ кодирования данных формы: enctype="multipart/form-data"
Метод передачи данных: method="POST"

Отправить этот файл: Загрузить

Весь код html и js разметки:
Отправить этот файл: Загрузить

Переходим к java script коду.
Для передачи файла необходимо передавать форму целиком:
$("form").submit(function(e) {

Считываем данные формы в переменную:
var formData = new FormData($(this));

Далее для передачи данных на веб-сервер используем технологию ajax.
В случае успешной передачи файла во всплывающем окне будет отображено соответствующее сообщение.
В случае возникновения ошибки или отсутствии файла будет отображено сообщение с текстом возникшей проблемы.
$.ajax({ url: "file.php", type: "POST", data: formData, async: false, success: function (msg) { alert(msg); }, error: function(msg) { alert("Ошибка!"); }, cache: false, contentType: false, processData: false });

Весь код на java script с использование jquery:

Теперь остался код на стороне сервера для приема данных с формы методом POST запроса.

Получаем корневую директорию сайта и назначаем папку для загрузки файлов:
$uploaddir = $_SERVER["DOCUMENT_ROOT"].DIRECTORY_SEPARATOR."uploads".DIRECTORY_SEPARATOR;

Считываем загружаемый файл:
$uploadfile = $uploaddir . basename($_FILES["userfile"]["name"]);

Проверяем загружен ли файл.
В соответствии с входящими данными назначаем сопровождающее сообщение.
Если файл не загружен, загружаем в директорию указанную в $uploadfile:
if (move_uploaded_file($_FILES["userfile"]["tmp_name"], $uploadfile)) { $out = "Файл корректен и был успешно загружен.\n"; } else { $out = "Возможная атака с помощью файловой загрузки!\n"; }

При выполнении указанных действий возвращается ответ.

Весь код на php:

Весь html код включая js:

Отправить этот файл: Загрузить $("form").submit(function(e) { var formData = new FormData($(this)); $.ajax({ url: "file.php", type: "POST", data: formData, async: false, success: function (msg) { alert(msg); }, error: function(msg) { alert("Ошибка!"); }, cache: false, contentType: false, processData: false }); e.preventDefault(); });

Скачать файл с исходным кодом:

Загрузка файлов или картинок на сервер является довольно типичной задачей. Но прогресс не стоит на месте и поэтому сейчас конечно же хочется, чтобы загрузка файлов происходила в фоновом режиме. Как правило ранее это можно было реализовать с использованием технологии 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).

#preloader {visibility: hidden;} Добавить информацию

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

//upload.php print_r($_FILES);

Теперь напишем наш серверный скрипт, который будет вызываться с помощью jQuery. Его задача перекинуть залитые файлы из временной директории сервера в нашу, допустим как мы решили в “tmp”, после чего показать их.

//upload.php function show_dir($dir) // функция показа картинок из tmp папки { $list = scandir($dir); unset($list,$list); foreach ($list as $file) { echo " "; } } foreach ($_FILES as $key => $value) { //перемещение файлов в tmp move_uploaded_file($value["tmp_name"], "tmp/".$value["name"]); } show_dir("./tmp/");

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

$(document).ready(function(){ $("#preloader").hide(); $("#file").bind("change", function(){ var data = new FormData(); var error = ""; jQuery.each($("#file").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(); } }); } }) });

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

UPD:

Если кому захочется добавить красоты, например прогресс бар, то для этого нам надо будет дописать несколько строк кода. В html шаблон мы добавим супер элемент из html5 – progress, а в js код, добавим несколько строк с объектом XMLHttpRequest.
И так, наш html дополнится следующим:

А в код 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 кода:

$(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").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("progress",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("Ошибка загрузки файлов"); } }); } }) });

Мы пробежались по нескольким основным методам для получения данных и их дальнейшей передаче AJAX-запросом. Теперь пришло время поговорить о том, как же можно загружать файлы с помощью AJAX . Еще до недавнего времени, способов загружать файлы без перезагрузки самой страницы, было не так уж и много (скрытый iframe, Flash). Они и сейчас используются по причине того, что еще остаются пользователи со старыми версиями браузеров, которых не коснулся прогресс. Но оглядываться назад не будем, посему шагаем в ногу со временем.

Рассмотрим, на мой взгляд, один из самых удобных способов для работы с файлами (и не только) - объект FormData . Пусть будет такая простенькая форма, для загрузки аватара пользователя:

HTML (файл index.html )

Ф.И.О:
Аватар:

Перейдем к JS-части. С полем "Ф.И.О" сложностей не будет и его используем только для наглядности того, что вместе с файлом, мы можем отправлять любые другие данные.

jQuery (файл script.js )

$(function(){ $("#my_form").on("submit", function(e){ e.preventDefault(); var $that = $(this), formData = new FormData($that.get(0)); // создаем новый экземпляр объекта и передаем ему нашу форму (*) $.ajax({ url: $that.attr("action"), type: $that.attr("method"), contentType: false, // важно - убираем форматирование данных по умолчанию processData: false, // важно - убираем преобразование строк по умолчанию data: formData, dataType: "json", success: function(json){ if(json){ $that.replaceWith(json); } } }); }); });

(*)Обратите внимание на то, что передаем форму не объектом jQuery, а DOM-элемент

PHP-обработчик (файл handler.php )



Понравилась статья? Поделиться с друзьями: