Загрузка файлов ajax с помощью JQuery.
Наконец то появилось время, и я оформил статью по теме онлайн загрузка файлов на сервер.
Для чего нам это нужно?
Если требуется загрузить не один файл, а много? Причем Flash технологиями пользоваться нельзя, или не хочется? А ждать обновления страницы после загрузки каждого файла, мягко говоря утомительно. Тогда нам на помощь приходит замечательный Ajax и не менее замечательный фреймоворк Jquery.
Для реализации задуманного, нам понадобятся 2 библиотеки JQuery
Скачать :
jquery.js
ajaxupload.js
Сразу же пример.
Естественно в нем я не загружаю файлы к себе на сервер. Загрузку имитирую функцией
Ну собственно код.
index.html
<head>
<title>Загрузка файлов Ajax с помощью Jquery</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="ajaxupload.js"></script>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="uploadButton" class="button">
<font>Загрузить</font>
<img id="load" src="loadstop.gif"/>
</div>
<ol id="files">
Загруженные файлы :
</ol>
</body>
</html>
script.js
var button = $('#uploadButton'), interval;
$.ajax_upload(button, {
action : 'upload.php',
name : 'myfile',
onSubmit : function(file, ext) {
// показываем картинку загрузки файла
$("img#load").attr("src", "load.gif");
$("#uploadButton font").text('Загрузка');
/*
* Выключаем кнопку на время загрузки файла
*/
this.disable();
},
onComplete : function(file, response) {
// убираем картинку загрузки файла
$("img#load").attr("src", "loadstop.gif");
$("#uploadButton font").text('Загрузить');
// снова включаем кнопку
this.enable();
// показываем что файл загружен
$("<li>" + file + "</li>").appendTo("#files");
}
});
});
upload.php
$uploadfile = $uploaddir.basename($_FILES['myfile']['name']);
move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile)
Ну собственно и все. Все достаточно просто и незаурядно.

спасибо очень помогло
Подскажите, люди добрые, как избавиться все-таки от белого прямоугольника в IE. Всю голову уже сломал (((
Или это только у меня такое.. особенность верстки какая-нить… может есть у кого работающий пример на каком-нить сайте – посмотреть.
Спасибо
Используйте вместо
<div id="uploadButton" class="button"> <font>Загрузить</font></blockquote>кнопку, Как пример
<button id="uploadButton" class="button">Загрузить</button>Попытался доработать сие решение. Нужно передавать помимо файла еще и некоторые параметры. В упор не пойму, почему первый файл грузится 1 раз, второй – два раза, третий – четыре… :(
А за решение – респект! скромно и со вкусом!
@ Константин
у меня вот так все отображается в плане ответа. Только помните, что основной скрипт, который отрабатывает ответ сервера ждет фразу ‘success’ как удачное завершение передачи файла, а в противном случае – неудача.
var button = $('#AP_uploadButton'), interval;
/*
$('#AP_uploadButton').onClick(function(){
this.css {
color: 'green';
};
});
*/
$.ajax_upload(button, {
action : 'upload.php',
name : 'myfile',
onSubmit : function(file, ext) {
// показываем картинку загрузки файла
//$("img#load").attr("src", "pic/load.gif");
//$("#AP_uploadButton").text('Загрузка');
/*
* Выключаем кнопку на время загрузки файла
*/
//this.disable();
$("" + file + "").appendTo("#files");
$("").appendTo("li[file='"+file+"']");
},
onComplete : function(file, response) {
// убираем картинку загрузки файла
//$("img#load").attr("src", "pic/loadstop.gif");
//$("#AP_uploadButton").text('Загрузить');
// снова включаем кнопку
//this.enable();
// показываем что файл загружен
//$("" + file + "").appendTo("#files");
$("img#load[file='"+file+"']").remove();//attr("src", "pic/loadstop.gif").attr("visibility","hidden");
$("input[name=filename]").val("");
},
onError : function(file, response) {
//this.enable();
//var thisFile = $("" + file + "");
$("li[file='"+file+"']").css({color:'red'});
$("Error: "+response+"").appendTo("li[file='"+file+"']");
},
onSuccess: function(file, response) {
$("li[file='"+file+"']").css({color:'green'});
$("Загружен").appendTo("li[file='"+file+"']");
}
});
});
Добрый вечер.
столкнулся с такой проблемой.
при загрузке файла мне надо его переименовывать..
т.е. в upload.php
заменил строку $uploadfile = $uploaddir.basename(time().’.jpg’);
но при выводе имени файла на основную страницу указывается изначальное. как можно решить эту проблему?
а как вывести файл,который загрузил?
как можно передать переменную вместе с файлом?
пробую в onSubmit: дописать строку -
this.settings.action = ‘upload.php?id=bg’
смотрю _GET d upload.php – Пусто!
Вопрос уже поднимался в комментариях
$.ajax_upload(button, {
data : {param:’1′},
@ Oksana
А кавычки важны? что то не передается параметр..
можете написать в асю 357054687,я так и не понял…
Скажите, а где здесь проверка размера файла, тип файла? Пытаюсь это сделать в upload.php, но возникла проблема. Как обратно возращать причину отказа загрузки файла? Например php скрипт понял, что файл больше 5 мб (максим -3 мб), то как он возратит обратно сообщение о том, что файл не соответсвует? Можно это сделать через js или ajax, чтоб он перед загрузкой файла проверяли это? Заранее спасибо!
Извините, прочитал все комментарии. Вопрос решён.
здравствуйте.
отличный плагин, но у меня вопрос возникает, который основан на проблемке одной….
используя ваш плагин мне нужно сохранить файл не в папку files/ а по другому пути. Пытался передать этот путь и через переменную и через get – и так и так получается, но…. если только писать “явным” образом, т.е.
…….
action: ‘loadFile.php?path=store/folder3/123/’,…..
или
……
data: ‘path: ‘store/folder3/123/’;',…….
ну или если передавать переменную инициализированную так же “явно”
var a = ‘store/folder3/123/’;
action: ‘loadFile.php?path=’ + path,
а вот если я “читаю” и записываю этот путь из HTML файла(текущего) т.е.
var path = $(‘#path’).text();
….
action: ‘loadFile.php?path=’+path,
…..
то путь не передается…..
однако при попытке вывода значения переменной как до и после – ВЫВОДИТ….
т.е.
…….
var path = $(‘#path’).text();
alert(path);
……..
…….
action: ‘loadFile.php?path=’ + path,
…..
onSuccess: function () {
alert(path);
}
……
и ДО начала загрузки и ПОСЛЕ выводит например store/folder3/123/
ОДНАКО сам файл загружается в родительскую папку store,
как я понимаю путь не передается…..
если сможете помочь буду ОООООООООЧЕНЬ преблагодарен ))))))
возможно смогу пояснить цель и поприсылать коды, но это в скайпе =)
соответственно содержимое loadFile.php
$uploaddir = $path;
$uploadfile = $uploaddir.basename($_FILES['myfile']['name']);
move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile);
и еще, возможен ли ответ от скрипта loadFile.php какой либо переменной и где её можно отловить и обработать? что то вроде например
$uploaddir = $path;
$uploadfile = $uploaddir.basename($_FILES['myfile']['name']);
move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile);
echo ‘bla bla bla’;
….. в JS.js
onComplete: function (file, response) {
var bla_bla = response;
alert(bla_bla);
}
спасибо =)
Доброе время суток! В поисках ответа набрела на Ваш блог, может подскажите, а то я скоро повешусь – третий день не могу решить проблему!!!
Использую этот же плагин, все устраивает, всем управляю, кроме одного!
Передача параметра. Задача следующая:
Клиент загружает картинку, ему превью показывается. Не нравится – загружает другую.
Что я делаю:
1.Когда загрузка состоялась, возврат с сервера ее имени и запись в input hidden document.ExpertRegistr.TempName_FilePhoto.value = resultMess; (ставила разные варианты, и синтаксис jquery, и просто JS, без разницы. Запись делаю в блоке onComplete: function(file, res)
2. Когда нажимает опять кнопку – передаюпараметр на сервак – имя файла из этого input. И вот тут косяк полный. Если параметр передаю как константу – нет вопросов – сервер ее видит. Если параметр идет как data: {param1: document.ExpertRegistr.TempName_FilePhoto.value} (или через GET в строке url – то все, эта переменная не приходит на сервак. Я не понимаю, ЧТО НЕ ТАК…. Помогите, пожайлуста!
А есть ли возможность выводить как-то html-код загруженных превьюшек. А то изображения на сервер то загружаются и на странице, где форма загрузки изображений они тоже показываются, но если посмотреть исходный код страницы, то спписок пуст.
То что делает JS с DOM элементами посмотреть можно только через FireBug или подобные утилиты.
А собственно зачем вам?
Хочу вернуть абсолютный путь до загруженной картинки, чтобы потом можно было с ним работать. А то получается, что картинка загрузилась, а знаю об этом только я а не PHP, можно конечно в MySQL базу написать, но не хотелось бы без повода ее дергать
Не понимаю чего вы хотите.
Как это так получается что картинка загрузилась а PHP об этом не знает?
Ты же с помощью PHP и загружаешь её.
Может это то что нужно?
if(move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile))
echo $uploadfile;
Я знаю, что плохо объясняю. :)
Мне просто нужно после того как изображение загрузилось, на страницы с кнопка “Загрузить”, получить путь до загруженного изображения, чтобы в последующем отправить его в базу.
Помимо загрузки изображения на этой же странице есть два текстовых поля, которые после Submit`а пишутся в базу.
Вот пара вариантов
1) Добавляйте информацию о картинке в БД сразу после загрузки
2) Выводите путь к картинке как я вам показал чуть выше и в JS, в функции onComplete : function(file, response) переменная response будет содержать этот путь
дальше можно запихнуть его в скрытое поле для того что бы потом при субмите сохранить
примерно так $(“#тут ID скрытого поля”).val(response);
Зравствуйте, присоеденюсь к вопросу ITShaman’a файл грузится нормально, новое имя ему присваивается, но как посмотреть это имя на странице отображения ?
т.е. рядом с кнопкой выводится исходное имя файла, а нужно конечное.
распишите по-подробней процедуру передачи этого имени из php в js ( если я правильно понял работу скрипта )
заранее спасибо.
В php скрипте пишите echo $newFileName;
В JS в функции onComplete : function(file, response) это имя будет в переменной response
Выводить по аналогии с моим примером $(“<li>” + response + “</li>”).appendTo(“#files”);
А можете поподробнее разжевать и привести пример реализации: дальше можно запихнуть его в скрытое поле для того что бы потом при субмите сохранить
примерно так $(“#тут ID скрытого поля”).val(response);
// убираем картинку загрузки файла
$("img#load").attr("src", "loadstop.gif");
$("#uploadButton font").text('Загрузить');
// снова включаем кнопку
this.enable();
// записываем сюда название файла
$(“#тут ID скрытого поля”).val(response);
}
upload.php
$uploadfile = $uploaddir.basename($_FILES['myfile']['name']);
if(move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile))
echo $uploadfile; // выводим имя загруженного файла с полным путем где он лежит.
если нужно было переименовать файл и выдать только название файла, то нужно было делать так
upload.php
$newFileName=General::translit(basename($_FILES['myfile']['name']));// здесь General::translit() переводит название файла в транслит
$uploadfile = $uploaddir.$newFileName;
if(move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile))
echo $newFileName; // выводим имя загруженного и переведенного в транслит файла.
Вроде все просто.
Я так понимаю, что в JS файл нужно вставить, к примеру: $(“#img”).val(response);
Я просто даже не совсем могу представить зачем вам это нужно.
Делаю сайт автообъявлений, где нужно заполнить несколько полей (значения передаются через post-запрос) и загрузить на сервер несколько изображений. Изображения загружаются так как нужно, но вот нужно передать вместе с post-запросом имена загруженных изображений
То есть у вас возникла проблема в том, что пока объявление не создано то некчему файл прикрепить?
Тогда ваше решение не есть good.
Представляете, пользователь загрузил файлов на 5 Гигов, а объявление так и не сохранил. И что делать?
Я в таких ситуациях делаю так: если загружается картинка, а объявление еще не сохранено, то оно автоматически сохраняется, и после этого загружается картинка и информация сразу заносится в БД. Если есть обязательные поля то они заполняются значениями по умолчанию. Допустим название может сохраниться так “(Без названия)”
У меня ограничение на размер загружаемых файлов стоит, а не задействованные изображения, я раз в неделю или реже буду подчищать скриптом.
Автоматически сохранять объявление не совсем мне подходит так как не хотелось бы видеть кучу мусорных объявлений. Да и базу лишний раз дергать не хотелось бы. Мне просто нужно получить имена загруженных изображений и отправить их в форме в виде скрытого поля.
*форму
Ну хорошо.
я вам показал как это сделать.
Возможно вам лучше будет организовать такой вариант загрузки файлов?
Интересное решение.
Вы простите меня, но в JS я как-то не силен, в PHP еще могу что-то наваять, а вот в JavaScript увы. Мне необходим предпросмотр изображений, который будут загружены на сервер. Приведенный метод на этой странице именно этим меня и зацепил, что позволяет это сделать. Я так понимаю, что если JS работает на стороне клиента, то теоретически можно показать изображение, которое он выбрал, используя путь локальный (на компьютере пользователя). Или я ошибаюсь?
Да, по моему так можно, но я всегда делал по другому.
тут 2 варианта:
1) можно создавать картнику;
2) можно создать ее при формировании страницы и потом поменять ей путь.
в upload.php
$uploaddir = ‘files/’;
$uploadfile = $uploaddir.basename($_FILES['myfile']['name']);
if(move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile))
echo $uploadfile;
в js
onComplete : function(file, response) {
$(“img#preview”).attr(“src”, response);
По вашим советам, я все таки реализовал передачу в скрытое поле, только передается самое последнее значение. А если несколько загруженных изображений. Можно ли как-нибудь сплюсовать все значения в JS-скрипте?
Можно. На вскидку 2 варианта предложу:
1) При загрузке изображений создавать скрытые поля с одним и тем же названием. Например images[]. Квадратные скобки обязательны.
2) Хранить все имена файлов в формате JSON в 1 скрытом поле.
Но это как по мне это не кашерно все.
А как можно все имена хранить в одном поле??
Яж написал JSON
Не сочтите за наглость, но не могли бы Вы привести код реализации
Почему-то если создавать скрытые поля с одним и тем же названием (к примеру, images[]), то передается только последнее загруженное изображение, доступное через переменную $_POST['img'][0], все остальные элементы массива пусты
*(к примеру, img[])
Спасибо большое, самое классное и кроссбраузерное решение.
Особенно здорово, что работает внутри тега form — получается “вложенная” форма.
Без скрытых фреймов и флеша.
Спасибо! Первое найденное мной решение, которое не висит кучу размера и имеет нечитабельный вид.
Подскажите как заставить этот скрипт работать если нет возможности использовать $(document).ready(function() { ????
Мне надо использовать события click или live !
Заранее спасибо.
Как бороться с You passed 0 elements to ajax_upload at once, а точнее с конфликтом с jquery-ui-1.8.16.custom.min.js???
При динамической загрузке <div id=”uploadButton” class=”button”> с помощью того же jquerj ваш скрипт не видит нужные div’ы.
Спасибо за скрипт.
Прикрутил за пару минут и настроил под себя. Очень легкий в интеграции и управлении!