One-Click Upload – плагин для аплоада файлов на jQuery

One-Click Upload – это плагин для jQuery, который способен заменить стандартный элемент формы для аплоада файлов, причем для этой цели можно использовать ссылки, изображения или любой другой элемент. После инициализации выбранного элемента, по нажатию на него будет отображаться диалог выбора файлов, а сама загрузка файла на сервер будет происходить без перезагрузки страницы. Используя этот плагин вы сможете настроить внешний вид элементов для загрузки файлов так, как вам нужно, в отличие от стандартного поля для загрузки файлов, вид которых крайне трудно изменить (см. пример здесь).

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

Пример

Для создания поля, воспользуемся простой ссылкой, а прогресс отправки файла будем показывать в элементе span=progress:

<a id="upload1" style="background: green; font-size: 24px; color: white;" href="#">Выберите файл</a>
<span id="progress1"></span>

Далее инициализируем поле (определяем его по id):

$('#upload1').upload({
	name: 'file',
	method: 'post',
	enctype: 'multipart/form-data',
	action: 'upload.php',
	onSubmit: function() {
		$('#progress1').text('Отправка файла...');
	},
	onComplete: function(data) {
		$('#progress1').text('Файл успешно отправлен');
	}
});

Ну и сохраняем его на стороне сервера (пример для PHP):

<?php
$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['file']['name']);

if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}
?>

Более подробно о плагине можно узнать на странице проекта Google Code.

Maklay.com - Большой каталог товаров для спорта и активного отдыха
  • http://arty.name arty

    а как же ненавязчивость? как оно будет без жс работать?

  • admin

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

  • http://1001doroga.ru Владис

    Интересно пишите. Подумайте о том, чтобы зарегистрироваться в Яндекс Каталоге, я почему-то думаю, что должны Вас принять. Настоящий проект у Вас, живой какой-то. :) А по программингу там щаз не так много сайтов, я вчера токо смотрел

  • admin

    @Владис
    Спасибо, заявку уже давно оставил, пока безрезультатно :)

  • http://arty.name/ arty

    не то, чтобы совсем нельзя
    разными нетривиальными способами это возможно : )
    например, прозрачным инпутом поверх ссылки

  • admin

    @arty
    Я ж не говорю, что нельзя, просто не совсем просто с этим делом возиться. Сам когда то делал это с прозрачным инпутом. А с плагином это легко и просто.

  • http://pokrovskii.com Максим Покровский

    Проверка на шелы есть? А то позаливают через него, потом не разгребешь..

  • admin

    @Максим Покровский
    Ну конечно же нет проверки. На JavaScript невозможно проверять то, что заливает пользователь. Это нужно делать на стороне сервера.

  • http://ad-boxes.vndv.com Антон

    Спасибо, очень хорошая библиотека эта, Jquery!!!

  • Saveliy

    Запустил , вроде показывает что файл загружает , а как увидеть куда он его грузит? проверяю на это же скрипте массив $_FILES ничего в нем нету ! как увидеть то файл?

  • admin

    @Saveliy
    Странно, $_FILES не должен быть пуст если файл нормально загружен. Может быть у вас лимит на загрузку файлов на сервер? Проверьте логи, может есть какая ошибка.

  • kevel

    Подключил. Все отлично работает на локале. Спасибо! Вот только на хостинге не работет :( Permission denied to get property HTMLDocument.body’ when calling method:…
    Можете объяснить в чем причина?

  • admin

    @kevel
    Не могу сказать определенно, но знаю точно что это ошибка только фаерфокса. Отсюда вопрос, работает ли скрипт в других броузерах. И еще, открывается ли окно выбора файла, и делается ли XMLHTTP запрос?

  • kevel

    не работает во всех браузерах:(. ругаеться на строку
    var response = $(myFrame.contentWindow.document.body).text();

  • admin

    @kevel
    Честно говоря, затрудняюсь сказать, что это за проблема (((

  • gibbzy

    у меня такая проблема что на class плагин не вешаеться
    тоесть
    <a href=” rel=”nofollow”>click</a>
    <a href=” rel=”nofollow”>click2</a>
    <a href=” rel=”nofollow”>click3</a>

    $(’.upl’).upload(….); – не работает
    если сделать обработку по клику
    <a href=” rel=”nofollow”>click</a>
    <href=” rel=”nofollow”>click2</a>
    <a href=” rel=”nofollow”>click3</a>

    и примерно так
    $(’.upl’).click(function(){
    var id = $(this).attr(’id’);
    $(’#'+id).upload(…..);
    });

    то тогда приходиться кликать 2 раза и в FF не работает

  • admin

    @gibbzy
    Во-первых, у вас в примере для ссылок не указан класс, так что перепроверьте, все ли у вас правильно. Проверьте, сколько объектов возвращает выражение $(’.upl’).
    Во-вторых, в последнем куске кода вы инициализируете ссылки по id. Точно также вы можете сделать не кликая по ссылкам, а например при событии onready:
    $(document).ready(function(){
    $(’.upl’).each(function(){
    var id = $(this).attr(’id’);
    $(’#'+id).upload(……);
    });
    });
    Точно не могу сказать, почему ваш код не работает в FF, тут надо реальный пример смотреть.

  • http://deleted gibbzy

    я указывал class просто его сьело форматтером
    c onready спасибо поробую

  • http://twitter.com/smileart Smile @rT

    Странная штука, но у меня в скрипте-обработчике файл не проходит проверку:

    if (is_uploaded_file($_FILES['file']['tmp_name']))
    {
    $this->logger->log(’NOT PHP FILE!’, Zend_Log::INFO);
    }
    else
    {
    $this->logger->log(’REAL PHP FILE!’, Zend_Log::INFO);
    }

    Соответственно через move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile) переноситься в destination он аж никак не желает!

    Может подскажете что может быть и в какую сторону копать-то???

    Спасибо!

  • admin

    @Smile @rT
    Вы используете Zend, а насколько я знаю он плохо работает с аплоадом файлов. Самому приходилось сталкиваться с этой проблемой. Вы вначале проверьте, он вообще получает то, что нужно?
    Zend_Debug::dump($_FILES);
    Поставьте это перед if.

  • http://twitter.com/smileart Smile @rT

    Как ни странно, файл, видимо, загружается… (для примера грузил BPlan.rar ) выдача дебага получилась такой:

    array(1) { ["file"] => array(5) { ["name"] => string(9) “BPlan.rar” ["type"] => string(15) “application/rar” ["tmp_name"] => string(65) “C:\Documents and Settings\username\Local Settings\Temp\php1AA.tmp” ["error"] => int(0) ["size"] => int(2941949) } }

  • http://twitter.com/smileart Smile @rT

    Проблема решилась методом: “Ляг поспи и все пройдет…”
    Просто отвлекся, а когда вернулся к скрипту все уже работало… %)

  • Joshuan

    Сначала не хотело работать. После обновления самой jquery до 1.2.6 всё заработало)

  • Виктор

    Привет всем!
    У меня проблема: один и тот же файл не может быть более одного раза подряд загружен – загрузка просто не работает. т.е. например когда открывается окно с выбором файл пусть например d:\foto\1.jpg – в первый раз загружается, потом снова нажимаю на кнопку загрузит и выбираю точно тот же файл – не загружает, если выбираю например d:\foto\2.jpg а потом снова d:\foto\1.jpg то уже грузится…
    Прописал следующий код $(”input:file”).val(”") в обработчик onComplete
    var uploader = $(’#upload1′).upload({
    name: ‘file’,
    method: ‘post’,
    autoSubmit: true,
    enctype: ‘multipart/form-data’,
    action: ‘upload.php,
    onComplete: function(data) {
    $(”input:file”).val(”");
    }
    });
    В мозиле этот негативный ньюанс был одолен, но в ИЕ никак не хочет.
    Думал может быть в ИЕ какой то кэш держит что не дает реагировать на выбор пусть даже и одинакового файла, как на новый вариант загрузки…
    В общем кто что знает, у кого какие иди есть…подскажите …буду крайне признателен..

  • admin

    @Виктор
    Мне кажется все же проблема с кэшем. Я думаю нужно попробовать каждый раз при загрузке отправлять запрос с разным URL, вроде этого: upload.php?rand=12345, т.е. на каждый запрос добавлять параметр со случайным числом. Попробуйте сделать это в onSelect:
    onSelect : function(){
    $(this).action += ‘?rand=’+Math.floor ( Math.random ( ) * 10001 );
    }

  • Виктор

    пробовал и так не получается…
    проблема не в кэше , а в том что значение поля file нужно очистить..в мозила команда
    $(”input:file”).val(””); очищает его , а в ИЕ нет
    проблема решается следующим образом
    onComplete: function(data) {
    var ff=document.getElementById(”iduplpers”);
    ff.reset();
    }
    где iduplpers это ID формы обрамляющее поле file
    P.S. саму библиотеку при этом пришлось подправить – дописать в нее свойство ID и передать его
    var uploader = $(’#upload1′).upload({
    name: ‘file’,
    method: ‘post’,
    ID: ‘iduplpers’,
    autoSubmit: true,
    enctype: ‘multipart/form-data’,
    action: ‘upload.php,

  • Slava0008

    2 Виктор
    Ваша проблема решается проще и не надо править саму библиотеку
    onComplete: function() { $(”form[target^='iframe']“)[0].reset(); }

  • enzo

    Перестало работать в Опере 10 :( . Что за ерунда не пойму, если запустить Dragonfly и выбрать опцию “Подсвечивать при наведении курсора”, то срабатывает без проблем. Кто-нибудь сталкивался? Кто пользуется протестировали на Опере 10?

    P.S. Вот все ругают семейство ослов, а последний IE несет в себе достойный отладчик JavaScript. Теперь больше всего проблем с Оперой, в которой средства отладки скриптов ужасно примитивные и сырые, а теперь еще и работает под ней не все :(

  • enzo

    Вот проект на эту тему, который развивается и исправляется:
    http://valums.com/ajax-upload/

  • admin

    @enzo
    Спасибо за ссылку. Насчет семейства ослов, то в основном по-моему ругали 6-ю версию, восьмерка гораздо лучше, и в плане отладки тоже. Чего всем им не хватает (в том числе и опере), так это консоли как в фаербаге.

  • enzo

    Конечно отладка в FF всех опережает на годы :) , но в IE 8 появиля нормальный отладчик JavaScript, местами он мне понравился даже больше, чем в FF (о ужас :) ), хотя динамично подгружаемый JS он тоже дебажит плохо (но Firebug его тоже не видит). Если раньше в IE требовалось ставить MS Visual Studio, то теперь в него встроен отладчик, которые адекватно позволяет отладивать код. Даже срабатывают инструкции “debugger;” (хотя и невсегда :) ), но в нем удобнее просмтривать свойства переменных в контрльных точках, в Firebug это все равно танцы с бубном и боязнь лишний раз сделать ошибку в назании переменной в окне свойств (Firebug таких ошибок не прощает). Хотя отладка с выводом в консоль в Firebug`е – это фактически предел мечтаний, а если использовать еще и FirePHP (кто не знает, многое теряет), то Firebug вообще идеальный отладчик. Что касается Opera, то где-то находил как можно сделать вывод в консоль DragonFly. Это не так удобно как в FireBug, но тоже вывод в консоль отладки сдлать можно, хотя и не такой удобный.

  • admin

    Во всем согласен. В Опере все хорошо, но просто непривычно как-то. О чем забыли, так это о Google Chrome. Честно скажу, его JavaScript отладчик мне понравился больше всех.

  • http://rupor.sampo.ru Andrey

    Для работы в Google Chrome нужна пропатченная версия скрипта. Взять можно здесь
    http://rupor.sampo.ru/sites/all/modules/static_storage/js/jquery.ocupload.js

  • http://ximinfo.com Химик

    а где исходники та? что то не до конца понял. Или к тому коду который тут только jquery подключить?

  • admin

    Нужно подключить jquery + плагин, который по ссылке указан.

  • http://code.google.com/p/upload-at-click/ Виталий

    Альтернатива.
    Без использования jQuery. http://code.google.com/p/upload-at-click/

JSToolbox создан на основе WordPress