Войти Регистрация

AJAX загрузка файлов на сервер + jQuery, IFRAME, PHP


ajax загрузка файловЭто очень интересная статья, о том, как загрузить файлы на сервер с помощью технологии AJAX. Как вы уже знаете, ajax это асинхронный javascript, который позволяет работать с сервером, не перезагружая страницы в браузере. Такая технология очень полезна для реализации нашей идеи: загрузить файлы на сервер не перезагружая страницы браузера. Наша идея также может быть реализована другими способами, обо всем этом читайте ниже в нашей статье.

Что мы сегодня узнаем?

Загрузка файлов на сервер на AJAX + jQuery + PHP

Загрузка нескольких файлов на сервер на AJAX + jQuery + PHP

Загрузка файлов на JS + IFRAME + PHP

Загрузка файлов на сервер на AJAX + jQuery + PHP

Реализация загрузки файлов на сервер с помощью AJAX, немного сложнее, чем просто отослать текстовый POST или GET запрос. Но не настолько сложно, чтобы понять и освоить эту методику. Если вы еще не совсем понимаете, как взаимодействуют AJAX и PHP, советую сначала прочитать статью о взаимодействии PHP и AJAX. Но, даже если вы не знаете, как работает технология AJAX, это не страшно, так как мы будем использовать библиотеку jQuery и плагин ajax_upload. И если вы будете следовать всем примерам и инструкциям шаг за шагом, то вы сможете реализовать отличный загрузчик файлов на сервер.

Суть метода: Мы создадим HTML образ загрузчика, который будет в себе содержать: файловое поле ввода, кнопку подтверждения, блок статуса загрузки (будут выводиться: «загружено» или «ошибка»), список ul (будут добавляться новые DOM элементы, другими словами это список загруженных файлов). На кнопку подтверждения мы создадим обработчик на языке JS, при этом будем использовать синтаксис jQuery, и передадим файл плагину ajax_upload, который отправит файл и все нужные данные на серверную сторону. Серверная сторона, это наше PHP приложение, которое сохранит файл в нужную папку и возвратит результат работы. Или же просто возвратит сообщение об ошибке, если что-то пойдет не так. Задание есть, приступим?

HTML код ajax загрузчика

Давайте создадим HTML файл, в котором будет каркас нашего загрузчика файлов. Приведу HTML код, потом объясню что и к чему.

<div id="upload" >Upload File</div>

<span id="status" ></span>

 <ul id="files" ></ul>

Как видите, HTML код ajax загрузчика, невыносимо сложный. Но все же стоит прояснить, что и к чему:

<divid="upload" >UploadFile</div> - это наша кнопка подтверждения загрузки файла на сервер. Далее приведу CSS код оформления.

<spanid="status" ></span> - это блок, в который мы будем помещать ответ серверной стороны приложения. Или «Загружено», или «Ошибка».

<ulid="files" ></ul> - это список файлов, которые были загружены на сервер, нашим jquery + ajax загрузчиком.

Как и было обещано, приведу ниже CSS код стиля, кнопки подтверждения загрузки файла:

#upload{

margin:30px 200px; padding:15px;

font-weight:bold; font-size:1.3em;

font-family:Arial, Helvetica, sans-serif;

text-align:center;

background:#f2f2f2;

color:#3366cc;

border:1px solid #ccc;

width:150px;

cursor:pointer !important;

-moz-border-radius:5px; -webkit-border-radius:5px;

}

Серверная PHP сторона приложения

Как упоминалось в сущности метода, серверная сторона всего лишь выполняет копирование (сохранение) файла и возвращает результат своей работы («Загружено» или «Ошибка»). Но, это только пример, на который полагаться не стоит. Здесь нет защиты от хакерских взломов, и не установлены ограничение на размер файлов. Если у вы будете создавать загрузчик для всеобщего пользования, то обязательно реализуйте вышеперечисленные дополнения. Ниже приведен PHP код примера загрузчика файлов, создайте файл с именем upload-file.php, и поместите в него следующий код:

<?php

$uploaddir = './uploads/';

$file = $uploaddir . basename($_FILES['uploadfile']['name']); 

if (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $file)) {echo "success";}

 else {echo "error";}

?>

Если внимательно присмотреться, то заметите что здесь все написано русским текстом, а точнее:

 $uploaddir – каталог на сервере, куда будут загружаться файлы.

$file – имя загружаемого файла, к которому прикрепляется путь к серверному каталогу.

Далее, если выполнено копирование файла на сервер, то выводим «Загружено» или, в случае непредвиденных проблем, выводим «Ошибка».

Самое простое уже сделано. Впереди самое интересное – jQuery + AJAX сторона загрузчика файлов.

JavaScript код

Как и в любом другом приложении, использующем JS, код должен быть помещен в шапку (head), документа. Еще одно важное замечание: перед написанием данного JS кода, не забудьте заранее подключить библиотеку jQuery и плагин ajax_upload. Если вы уже это сделали, отлично, приступим к написанию кода:

$(function(){

var btnUpload=$('#upload');

var status=$('#status');

new AjaxUpload(btnUpload, {

action: 'upload-file.php',

//Имя файлового поля ввода

name: 'uploadfile',

onSubmit: function(file, ext){

if (! (ext && /^(jpg|png|jpeg|gif)$/.test(ext))){

// Валидация расширений файлов

status.text(Только JPG, PNG, GIF файлы');

return false;

 

}

status.text('Uploading...');

},

onComplete: function(file, response){

//Очищаем текст статуса

status.text('');

//Добавляем загруженные файлы в лист

if(response==="success"){

$('<li></li>').appendTo('#files').html('<img src="./uploads/'+file+'" alt="" /><br />'+file).addClass('success');

} else{

$('<li></li>').appendTo('#files').text(file).addClass('error');

}

}

});

});

Сначала, мы инициализируем доступ к кнопке подтверждения загрузки, и записываем в переменную btnUpload. Заодно и получаем доступ к блоку серверных сообщений (status). Далее идет работа с плагином ajaxupload. Создаем новый объект и указываем нужные нам параметры:

Action – путь к нашему серверному обработчику загруженных файлов.

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

onSubmit – Функции, которые выполняются перед ajax загрузкой файлов на сервер. В нашем случае, это валидация загружаемых файлов (проверка поддерживаемых расширений). Но опять, проверка, как говорится для «недалеких», эту проверку легко обойти, поэтому стоит еще раз проверять на серверной стороне приложения.

status.text – текст, который выводится в процессе ajax загрузки файлов на сервер. Заметьте, если файлы не поддерживаемые, то выводится сообщение об ошибке.

onComplete – Запускаем функцию по завершению загрузки файла на сервер. В этой функции: очищаем значение status.text; добавляем загруженные файлы в лист files.

Как видите загрузить файлы на сервер с помощью AJAX, проще, чем казалось. Но все-таки, меня смущает наличие библиотеки jQuery в данном методе. И если вы знаете, как реализовать ajax загрузку файлов без использования jQuery, убедительная просьба сообщить в комментариях к статье.

Далее мы рассмотрим более развитый метод ajax загрузки файлов, который позволяет загружать несколько файлов одновременно.

Загрузка нескольких файлов на сервер на AJAX, jQuery, PHP

Если вам, для личных нужд, необходимо сделать красивую загрузку нескольких файлов на сервер с помощью AJAX и PHP, то вам придется использовать некоторые дополнения к библиотеке jQuery. А именно:

jQuery Form Plugin v2.18

 Плагин для корректной ajax работы с полями и формами.

 Где взять: www.malsup.com/jquery/form/

jQuery BlockUI Plugin v2.14

 Плагин, позволяющий выводить красивые сообщения об ошибке.

 Где взять: www.malsup.com/jquery/block/

jQuery Multiple File Upload Plugin v1.31

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

 Где взять: www.fyneworks.com/jquery/multiple-file-upload/

Если вы уже скачали все эти плагины, и само собой, библиотеку jQuery, можем приступать к разработке. Также, нам необходимо создать PHP файл, как и в предыдущем примере, который будет обрабатывать данные на серверной стороне. Назовем его: doajaxfileupload.php. Теперь, поподробнее.

jQuery Form Plugin – отличный плагин, он используется для отправки файлов на сервер методом ajax. Этому плагину, можно найти и другие применения.

jQuery BlockUI Plugin – используется в эстетических целях, для вывода красивых сообщений о корректности работы плагина MultipleFileUploadPlugin.

MultipleFileUploadPlugin – этот плагин, основа нашего мульти файлового загрузчика. Он позволяет выбрать несколько файлов. При этом, он имеет гибкие настройки, для ограничения типа файлов, установки количества загружаемых файлов, проверяет файл на дубликаты (если такой файл уже выбран) и т.д.

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

В файле index.php, думаю и так все понятно. Здесь находится, собственно форма загрузки файлов и подключаются библиотека jQuery и все необходимые плагины для работы с ajax. Несколько слов по коду и настройке плагинов:

$('.MultiFile').MultiFile({ 

   accept:'jpg|gif|bmp|png|rar', max:15, STRING: { 

     remove:'удалить',

     selected:'Выбраны: $file', 

     denied:'Неверный тип файла: $ext!', 

     duplicate:'Этот файл уже выбран:\n$file!' 

 }});

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

$("#loading").ajaxStart(function(){({

  ...

 });

Показывает и убирает анимацию при ajax загрузке файлов на сервер.

$('#uploadForm').ajaxForm({

  ...

 });

Отвечает за отправку файлов на сервер.

doajaxfileupload.php – это наша серверная сторона приложения, в нем все достаточно понятно, если вам необходимо, можете отредактировать на свой вкус.

Пожалуй, все о загрузке нескольких файлов на сервер методом AJAX, jQuery и PHP. Надеюсь, у вас все работает, также хорошо как у меня.

Загрузка файлов на JS + IFRAME + PHP

Если вы поклонник не красоты, а функциональности и компактности кода, то для вас есть хорошая новость. Загружать файлы на сервер без перезагрузки страницы, можно не только с помощью AJAX и всяких там jQuery плагинов. Также, это можно реализовать с помощью простого JavaScript, iframe (фреймов) и php (он всегда необходим). Дело в том, что на AJAX, невозможно реализовать загрузку файлов. XmlHttpRequest не способный загружать файлы. Хотя, это можно обойти. С помощью технологии Remote Scripting. В частности используя IFRAME. Интересно то, что мы будем создавать форму как при обычной загрузке файлов, только в форме мы будем указывать target="rFrame", ссылаться на скрытый iframe, который будет перезагружен, но визуально этого не отобразиться. После перезагрузки, из серверной php стороны приложения, будет возвращен JS вызов функции, который завершит загрузку файла.

Данный загрузчик простой, состоит из двух файлов, и весит около 1 КБ. Ближе к делу. Создайте ваш HTML файл и поместите туда код:

<html>  

<head>  

<script type="text/javascript">  

 function onResponse(d) {  

 eval('var obj = ' + d + ';');  

 alert('Файл ' + obj.filename + (obj.success ? " " : " НЕ ") +  

    "загружен.");  

 }  

 </script>  

</head>  

<iframe id="rFrame" name="rFrame" style="display: none">  

</iframe>  

<form action="handler.php" target="rFrame" method="POST"  

   enctype="multipart/form-data">  

<input type="file" name="loadfile">  

<input type='submit' value='Загрузить'>  

</form>  

</html>

Здесь мы видим практически те же компоненты, что и при простой загрузке файлов на сервер, только: target="rFrame" – про который мы уже говорили выше; функция onResponse – она получает JSON объект, который мы присылаем из серверной стороны. Также, не забудьте указать multipart/form-data, без которого, форма не будет загружать файлы. Далее, посмотрим на серверный код, файла handler.php:

<?php  

 function jsOnResponse($obj)  

 {  

 echo ' 

 <script type="text/javascript"> 

 window.parent.onResponse("'.$obj.'"); 

 </script> 

 ';  

 }  

  

 $dir = '/uploads'; // путь к каталогу загрузок на сервере  

 $name = basename($_FILES['loadfile']['name']);  

 $file = $dir . $name;  

  

 $success = move_uploaded_file($_FILES['loadfile']['tmp_name'], $file);  

 jsOnResponse("{'filename':'" . $name . "', 'success':'" . $success . "'}");  

  

?>

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

Очень простой и интересный скрипт. Конечно, вы можете усовершенствовать его.

 Надеюсь, у вас все работает и не выкидывает ошибок. Если вы имеете другие познания, о том, как загрузить файл на сервер с помощью AJAX, просьба, поделиться с другими в комментариях.



Дальше: PHP парсинг HTML, с помощью simple HTML DOM


Дискуссия по теме    34 Комментария 
Добавить комментарий
Олег Петрович 22.02.2015 в 16:55
ребята подскажите, в линуксе фаил загрузился на сервер его владелец стоит xxx-data ну и прав доступа нет, ничего с ним сделать нельзя. Как побороть?
Сергей 31.07.2014 в 14:57
status.text(Только JPG, PNG, GIF файлы'); кавыЯку забыли
Алексей 25.07.2014 в 16:12
Статья отличная. Только вот без ссылки на файл плагина в первом случае толку от нее не какого. Хоть в комментариях и кидают ссылки на аналогичные плагины, толку все равно нет т.к. в любом случае придется разбираться самому.
сержик 18.04.2014 в 16:00
Благодарствую!
Кашурин Сергей 09.04.2014 в 12:04
Благодарю Автора за такую замечательную статью. К сожалению в моём проекте данный пример не сразу заработал, echo скрипт из php файла писал скрипт в iframe, и как следствие результата в главном окне не было. Я немного модифицировал script и получилось следующее: onResponse = function(d) { eval('var obj = ' d ';'); alert('Файл ' obj.filename (obj.success ? " " : " НЕ ") "загружен."); } Т.е. function onResponse(d) { я изменил на onResponse = function(d) { и это сработало.
Леван 02.02.2014 в 21:16
Статья классная, но я нигде не нашёл файла ajax_upload, скиньте пожалуйста ссылку
Тарас 04.02.2014 в 08:02
Смотрите комментарии ниже... кому-то уже скидывал, или возможно найдете другое решение (аплоадер)
Роман 24.01.2014 в 16:56
Где взять скрипт ? Нет ни в архиве не на гетхабе.
Тарас 25.01.2014 в 07:02
Воспользуйтесь этим http://blueimp.github.io/jQuery-File-Upload/ на данный момент самый надежный из загрузчиков. или вот... http://github.com/Valums-File-Uploader/file-uploader этот разбирал полностью, он не большой, день два покопаться и можно понять все.
vakhtang 30.07.2013 в 20:43
отстой нет файла ajax_upload.js из за этого зря потрачено время на статью, хотя сама статья написана очень хорошо просто и понятно, вот только если бы прилагался файл то все было бы супер
Костя 01.07.2013 в 20:56
Спасибо, хорошая статья Если не сложно, есть ли у последнего способа ограничения на размер файла?
Я 13.05.2013 в 15:39
Работает нормально?
Дима 02.04.2013 в 16:35
Можно ли через Аякс передать файл выбранный в <input type=file> на скрипт php и как ???
Тарас 03.04.2013 в 23:52
Можно. Копайте этот скрипт http://github.com/Valums-File-Uploader/file-uploader
tvim 15.03.2013 в 18:43
Подскажите если использовать 3 вариант. Например пользователь нажмет на кнопку загрузки несколько раз в то время когда загружается файл что произойдет?
Гость 25.12.2012 в 21:27
Каким образом обработать дополнительные input'ы? К примеру: <input class="text" name="title" id="title">
Fly 09.12.2012 в 14:49
Автор, спасибо за статью. Реально интересно и всё по теме. Заработало почти сразу, почти, потому что сначала невнимательно прочёл. Делал по первому варианту и пропустил момент, что нужно догрузить upload плагин. P.S. Не слушай ленивых дебилов, которые привыкли кодить копипастом не включая голову. Материал отличный.
Дмитрий 03.10.2012 в 20:33
Вопрос по первому варианту. При загрузке файла я использую PHP-функцию uniqid() для генерации случайного имени для файла. Как в поле <ul id="files" ></ul> сделать, чтобы показывало название загруженного файла, а не загружаемого?
Тарас 03.10.2012 в 22:01
Из PHP скрипта вернуть не просто "error" или "success", а json обьект в котором будет указанно имя загруженного файла. Например, пусть php скрипт, через echo возвратит следующую строку: {"result": "success", "filename": "generated-filename.jpg"} Тогда в функции onComplete (это уже js), мы получим не просто текст в переменной response, а обьект с несколькими значениями... после чего начинаем разбирать этот ответ: if(response.result == 'success') { $('<li></li>').appendTo('#files').html('<img src="' response.filename '"/>').addClass('success'); } как-то так... если возникнут проблемы, с обработкой json обьекта на стороне js, есть хорошая функция, которая выводит объект как строку, так можно посмотреть, что вернулось из сервера. Для этого вставьте следующий код в начале функции onComplete: alert(JSON.stringify(response));
smith 15.08.2012 в 15:26
"doajaxfileupload.php – это наша серверная сторона приложения, в нем все достаточно понятно, если вам необходимо, можете отредактировать на свой вкус." - нихрена непонятно,обьяснять надо нормально а не только копировать с хабра статьи
Тарас 19.08.2012 в 18:20
Печально, что вам не понятно... $fileElementName - имя получаемого массива с файлами далее, если массив error не пустой, обрабатываем разные варианты ошибок... далее, если массив с файлами пустой, то сформирует сообщение "нет загружаемых файлов" в конце-концов, если все хорошо, формирует сообщение с именем и размером загруженного файла. После чего удаляем файл из буфера - @unlink($_FILES['fileToUpload']); После этого с помощью echo возвращаем данные на страницу... данные в json формате.
Николай 04.07.2012 в 13:40
Автор, ну неужели тяжело выложить 2 файла JS которые нужны для работы? Зачем тратить столько времени на написание статьи, если без них нихрена не работает! Скачать ажакс аплоад мне так и не удалось, спасибо за потраченные в никуда 2 часа жизни!
Тарас 04.07.2012 в 15:46
Сожалею, что вы потратили 2 часа времени. Моей вины нету в том, что вы не можете разобраться в коде и как скачать файл. Вот прямая ссылка на архив плагина: http://github.com/valums/file-uploader/zipball/master - в архиве есть и демка и все что нужно, разбирайтесь... Насколько я понимаю, вы хотите чтобы кто-то за вас все сделал и обьяснил как использовать.
Андрей 08.06.2012 в 02:56
А где взять плагин ajaxupload?
Тарас 08.06.2012 в 21:55
Вот здесь: http://valums.com/ajax-upload/
Игорь 30.05.2012 в 12:19
Спасибо - интересно это в функцию ответа можно вставить скрытый импут со значением полного пути к картинке и где описали ограничения?
1 30.05.2012 в 07:15
Хорошая статья спасибо.
Гость 06.05.2012 в 22:54
status.text(Только JPG, PNG, GIF файлы'); Перед словом ТОЛЬКО мне кажется нужна одинарная кавычка '
Artemeey 29.03.2012 в 10:46
Код невыносимо сложный... Интересный юмор.
Тарас 29.03.2012 в 13:06
Что вы имеете в виду?
имя 19.01.2012 в 16:53
интересно, а автор смотрел код упомянутых плагинов, прежде чем выделять JS IFRAME PHP в отдельный вид? указанные плагины действуют тем же методом, только создают все элементы на лету. особенно фрейм, так как фрейм вставленный в html-код при загрузке страницы сгенерирует лишнее событие onload. хм, обязательно пишется без мягкого знака после Б
Ruzarh 18.12.2011 в 13:33
Я бы изменил последний пример на следующее dir = dirname(__FILE__) .'\uploads\\'; И да спасибо. Единственный нормальный пример который дает мне отправную точку в IFrame путешествие. Авторам спасибо еще раз.
Макс 08.12.2011 в 18:44
Спасибо за статью, то что надо сейчас попробую.
Злой Джек 19.11.2011 в 14:11
Все и ничего. Ни демки. Отстой
Добавить комментарий
Просмотров: 93307