Главная > JavaScript > Загрузка файлов ajax с помощью JQuery.

Загрузка файлов ajax с помощью JQuery.

Downloads

Наконец то появилось время, и я оформил статью по теме онлайн загрузка файлов на сервер.
Для чего нам это нужно?
Если требуется загрузить не один файл, а много? Причем Flash технологиями пользоваться нельзя, или не хочется? А ждать обновления страницы после загрузки каждого файла, мягко говоря утомительно. Тогда нам на помощь приходит замечательный Ajax и не менее замечательный фреймоворк Jquery.

Для реализации задуманного, нам понадобятся 2 библиотеки JQuery

Скачать :
jquery.js
ajaxupload.js

Сразу же пример.

пример

Естественно в нем я не загружаю файлы к себе на сервер. Загрузку имитирую функцией

sleep("3");

Ну собственно код.

index.html

<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

$(document).ready(function() {

      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

$uploaddir = 'files/';
$uploadfile = $uploaddir.basename($_FILES['myfile']['name']);
move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile)

Ну собственно и все. Все достаточно просто и незаурядно.

Скачать пример

Поделиться в соц. сетях

Опубликовать в Google Buzz
Опубликовать в Google Plus
Опубликовать в LiveJournal
Опубликовать в Мой Мир
Опубликовать в Одноклассники
Опубликовать в Яндекс

JavaScript , ,

  1. Dima
    25 Март 2011 из 20:28 | #1

    спасибо очень помогло

  2. 17 Апр 2011 из 13:47 | #2

    Подскажите, люди добрые, как избавиться все-таки от белого прямоугольника в IE. Всю голову уже сломал (((
    Или это только у меня такое.. особенность верстки какая-нить… может есть у кого работающий пример на каком-нить сайте – посмотреть.
    Спасибо

  3. 17 Апр 2011 из 15:58 | #3

    Используйте вместо

          <div id="uploadButton" class="button">
                <font>Загрузить</font></blockquote>
    

    кнопку, Как пример

          <button id="uploadButton" class="button">Загрузить</button>
    
  4. 22 Апр 2011 из 21:42 | #4

    Попытался доработать сие решение. Нужно передавать помимо файла еще и некоторые параметры. В упор не пойму, почему первый файл грузится 1 раз, второй – два раза, третий – четыре… :(
    А за решение – респект! скромно и со вкусом!

  5. 22 Апр 2011 из 21:48 | #5

    @ Константин
    у меня вот так все отображается в плане ответа. Только помните, что основной скрипт, который отрабатывает ответ сервера ждет фразу ‘success’ как удачное завершение передачи файла, а в противном случае – неудача.

    $(document).ready(function() {

          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+"']");
                }
              });
        });
  6. BJlag
    30 Май 2011 из 20:46 | #6

    Добрый вечер.
    столкнулся с такой проблемой.

    при загрузке файла мне надо его переименовывать..
    т.е. в upload.php

    заменил строку $uploadfile = $uploaddir.basename(time().’.jpg’);

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

  7. Виталий
    13 Июль 2011 из 18:12 | #7

    а как вывести файл,который загрузил?

  8. Алексей
    14 Июль 2011 из 16:27 | #8

    как можно передать переменную вместе с файлом?

    пробую в onSubmit: дописать строку -
    this.settings.action = ‘upload.php?id=bg’

    смотрю _GET d upload.php – Пусто!

  9. Алексей
    14 Июль 2011 из 16:55 | #10

    @ Oksana
    А кавычки важны? что то не передается параметр..

  10. Виталий
    19 Июль 2011 из 17:20 | #11

    можете написать в асю 357054687,я так и не понял…

  11. Кирилл
    19 Июль 2011 из 21:56 | #12

    Скажите, а где здесь проверка размера файла, тип файла? Пытаюсь это сделать в upload.php, но возникла проблема. Как обратно возращать причину отказа загрузки файла? Например php скрипт понял, что файл больше 5 мб (максим -3 мб), то как он возратит обратно сообщение о том, что файл не соответсвует? Можно это сделать через js или ajax, чтоб он перед загрузкой файла проверяли это? Заранее спасибо!

  12. Кирилл
    19 Июль 2011 из 22:29 | #13

    Извините, прочитал все комментарии. Вопрос решён.

  13. Володя
    28 Июль 2011 из 0:15 | #14

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

    если сможете помочь буду ОООООООООЧЕНЬ преблагодарен ))))))
    возможно смогу пояснить цель и поприсылать коды, но это в скайпе =)

  14. Володя
    28 Июль 2011 из 11:00 | #15

    соответственно содержимое 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);
    }

    спасибо =)

  15. 17 Авг 2011 из 21:24 | #16

    Доброе время суток! В поисках ответа набрела на Ваш блог, может подскажите, а то я скоро повешусь – третий день не могу решить проблему!!!
    Использую этот же плагин, все устраивает, всем управляю, кроме одного!
    Передача параметра. Задача следующая:
    Клиент загружает картинку, ему превью показывается. Не нравится – загружает другую.
    Что я делаю:
    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 – то все, эта переменная не приходит на сервак. Я не понимаю, ЧТО НЕ ТАК…. Помогите, пожайлуста!

  16. 12 Окт 2011 из 13:37 | #17

    А есть ли возможность выводить как-то html-код загруженных превьюшек. А то изображения на сервер то загружаются и на странице, где форма загрузки изображений они тоже показываются, но если посмотреть исходный код страницы, то спписок пуст.

  17. 12 Окт 2011 из 14:03 | #18

    То что делает JS с DOM элементами посмотреть можно только через FireBug или подобные утилиты.
    А собственно зачем вам?

  18. 13 Окт 2011 из 16:11 | #19

    Хочу вернуть абсолютный путь до загруженной картинки, чтобы потом можно было с ним работать. А то получается, что картинка загрузилась, а знаю об этом только я а не PHP, можно конечно в MySQL базу написать, но не хотелось бы без повода ее дергать

  19. 13 Окт 2011 из 18:59 | #20

    Не понимаю чего вы хотите.
    Как это так получается что картинка загрузилась а PHP об этом не знает?
    Ты же с помощью PHP и загружаешь её.
     
    Может это то что нужно?
    if(move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile))
    echo $uploadfile;

  20. 13 Окт 2011 из 20:38 | #21

    Я знаю, что плохо объясняю. :)

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

    Помимо загрузки изображения на этой же странице есть два текстовых поля, которые после Submit`а пишутся в базу.

  21. 13 Окт 2011 из 21:52 | #22

    Вот пара вариантов
    1) Добавляйте информацию о картинке в БД сразу после загрузки
    2) Выводите путь к картинке как я вам показал чуть выше и в JS, в функции onComplete : function(file, response) переменная response будет содержать этот путь
     
    дальше можно запихнуть его в скрытое поле для того что бы потом при субмите сохранить
    примерно так $(“#тут ID скрытого поля”).val(response);

  22. Demios
    23 Окт 2011 из 0:08 | #23

    Зравствуйте, присоеденюсь к вопросу ITShaman’a файл грузится нормально, новое имя ему присваивается, но как посмотреть это имя на странице отображения ?
    т.е. рядом с кнопкой выводится исходное имя файла, а нужно конечное.
    распишите по-подробней процедуру передачи этого имени из php в js ( если я правильно понял работу скрипта )
    заранее спасибо.

  23. 23 Окт 2011 из 14:07 | #24

    В php скрипте пишите echo $newFileName;
    В JS в функции  onComplete : function(file, response) это имя будет в переменной response
    Выводить по аналогии с моим примером $(“<li>” + response + “</li>”).appendTo(“#files”);

  24. 31 Окт 2011 из 18:51 | #25

    А можете поподробнее разжевать и привести пример реализации: дальше можно запихнуть его в скрытое поле для того что бы потом при субмите сохранить
    примерно так $(“#тут ID скрытого поля”).val(response);

  25. 31 Окт 2011 из 19:04 | #26
    onComplete : function(file, response) {
                  // убираем картинку загрузки файла
                  $("img#load").attr("src", "loadstop.gif");
                  $("#uploadButton font").text('Загрузить');

                  // снова включаем кнопку
                  this.enable();

                  // записываем сюда название файла
                  $(“#тут ID скрытого поля”).val(response);

                }

    upload.php

    $uploaddir = 'files/';
    $uploadfile = $uploaddir.basename($_FILES['myfile']['name']);
    if(move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile))
    echo $uploadfile; // выводим имя загруженного файла с полным путем где он лежит.

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

    $uploaddir = 'files/';
    $newFileName=General::translit(basename($_FILES['myfile']['name']));// здесь General::translit() переводит название файла в транслит
    $uploadfile = $uploaddir.$newFileName;
    if(move_uploaded_file($_FILES['myfile']['tmp_name'], $uploadfile))
    echo $newFileName; // выводим имя загруженного и переведенного в транслит файла.

    Вроде все просто.

  26. 31 Окт 2011 из 19:07 | #27

    Я так понимаю, что в JS файл нужно вставить, к примеру: $(“#img”).val(response);

  27. 31 Окт 2011 из 19:12 | #28

    Я просто даже не совсем могу представить зачем вам это нужно.

  28. 31 Окт 2011 из 19:17 | #29

    Делаю сайт автообъявлений, где нужно заполнить несколько полей (значения передаются через post-запрос) и загрузить на сервер несколько изображений. Изображения загружаются так как нужно, но вот нужно передать вместе с post-запросом имена загруженных изображений

  29. 31 Окт 2011 из 19:45 | #30

    То есть у вас возникла проблема в том, что пока объявление не создано то некчему файл прикрепить?
    Тогда ваше решение не есть good.
    Представляете, пользователь загрузил файлов на 5 Гигов, а объявление так и не сохранил. И что делать?
     
    Я в таких ситуациях делаю так: если загружается картинка, а объявление еще не сохранено, то оно автоматически сохраняется, и после этого загружается картинка и информация сразу  заносится в БД. Если есть обязательные поля то они заполняются значениями по умолчанию. Допустим название может сохраниться так “(Без названия)”

  30. 31 Окт 2011 из 21:37 | #31

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

    Автоматически сохранять объявление не совсем мне подходит так как не хотелось бы видеть кучу мусорных объявлений. Да и базу лишний раз дергать не хотелось бы. Мне просто нужно получить имена загруженных изображений и отправить их в форме в виде скрытого поля.

  31. 31 Окт 2011 из 21:38 | #32

    *форму

  32. 31 Окт 2011 из 23:18 | #33

    Ну хорошо.
    я вам показал как это сделать.
    Возможно вам лучше будет организовать такой вариант загрузки файлов?

  33. 01 Ноя 2011 из 6:16 | #34

    Интересное решение.

    Вы простите меня, но в JS я как-то не силен, в PHP еще могу что-то наваять, а вот в JavaScript увы. Мне необходим предпросмотр изображений, который будут загружены на сервер. Приведенный метод на этой странице именно этим меня и зацепил, что позволяет это сделать. Я так понимаю, что если JS работает на стороне клиента, то теоретически можно показать изображение, которое он выбрал, используя путь локальный (на компьютере пользователя). Или я ошибаюсь?

  34. 01 Ноя 2011 из 8:15 | #35

    Да, по моему так можно, но я всегда делал по другому.
    тут 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);

  35. 03 Ноя 2011 из 22:01 | #36

    По вашим советам, я все таки реализовал передачу в скрытое поле, только передается самое последнее значение. А если несколько загруженных изображений. Можно ли как-нибудь сплюсовать все значения в JS-скрипте?

  36. 03 Ноя 2011 из 23:05 | #37

    Можно. На вскидку 2 варианта предложу:
    1) При загрузке изображений создавать скрытые поля с одним и тем же названием. Например images[]. Квадратные скобки обязательны.
    2) Хранить все имена файлов в формате JSON в 1 скрытом поле.
    Но это как по мне это не кашерно все.

  37. 03 Ноя 2011 из 23:21 | #38

    А как можно все имена хранить в одном поле??

  38. 03 Ноя 2011 из 23:36 | #39

    Яж написал JSON

  39. 04 Ноя 2011 из 0:00 | #40

    Не сочтите за наглость, но не могли бы Вы привести код реализации

  40. 04 Ноя 2011 из 0:39 | #41

    Почему-то если создавать скрытые поля с одним и тем же названием (к примеру, images[]), то передается только последнее загруженное изображение, доступное через переменную $_POST['img'][0], все остальные элементы массива пусты

  41. 04 Ноя 2011 из 0:40 | #42

    *(к примеру, img[])

  42. 14 Ноя 2011 из 22:20 | #43

    Спасибо большое, самое классное и кроссбраузерное решение.
    Особенно здорово, что работает внутри тега form — получается “вложенная” форма.
    Без скрытых фреймов и флеша.

  43. 10 Дек 2011 из 17:31 | #44

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

  44. Дмитрий
    08 Янв 2012 из 22:42 | #45

    Подскажите как заставить этот скрипт работать если нет возможности использовать $(document).ready(function() { ????

    Мне надо использовать  события click или live !

    Заранее спасибо. 

  45. Дмитрий
    09 Янв 2012 из 13:26 | #46

    Как бороться с You passed  0  elements to ajax_upload at once, а точнее с конфликтом с jquery-ui-1.8.16.custom.min.js???

  46. Дмитрий
    09 Янв 2012 из 14:31 | #47

    При динамической загрузке <div id=”uploadButton” class=”button”> с помощью того же jquerj ваш скрипт не видит нужные div’ы.

  47. 25 Янв 2012 из 14:45 | #48

    Спасибо за скрипт.
    Прикрутил за пару минут и настроил под себя. Очень легкий в интеграции и управлении! 

Страницы комментариев
  1. Трекбеков пока нет.