Как стать автором
Обновить

Комментарии 61

Пригодится, положил в копилку.
Для подсветки кода используйте тег source с атрибутом lang
про HTML5 пишем, но HTML5 не используем :),
Тэг source на хабре к HTML5 отношения не имеет.
…А, в статье? Так Хабр всё равно XHTML 1.0 Transitional.
Спасибо, поправил.
А что, в Опере уже работает? Сразу пошел на gmail проверить, но там облом :(
Может кто-нибудь бросить ссылку на страницу с примером drag&drop?
Нет, в Opera поддержки Drag And Drop пока нет.
и в IE, злит, так как из-за одного исключения возникают две формы интерфейса, оговорка в справке и т.д.
Удобно. Сейчас попытаюсь повторить у себя. Будем ждать спецификации HTML5. :)
Похоже на удобный способ выкачивать скрытно у пользователя его приватные файлы (пароли и т.п.) просто предлагая сыграть в puzzle-подобную игрушку. Под курсор ставим скрытый iframe с локальным file://URL и даем перетаскивать все подряд к нам. А если не только файлы, но и букмарки/прочее таким образом можно будет перетаскивать, то откроется большое поле для сбора приватной инфы.

Я не скептик, но как то с опаской смотрю на такие нововведения…
Попробуйте так сделать и удивитесь =)
Что-то мне подсказывает, что еще будут об этом писать…
Стандарты это хорошо, но реализация часто хромает. Если сейчас сделать все грамотно и перетаскивать локальные файлы будет не возможно, то завтра кто-то в браузер встроит плагин, где в окне будут открыты файлы из какого-нибудь cloud хранилища. И как фичу сделают возможность перетаскивать эти файлы (все события, dataTransfer интерфейсы и т.п.). Вдруг внезапно «откроется брешь в безопасности».

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

P.S. я думал карма ь это отношение участников к адекватности автора, а не оценка его взглядов. «Заминусованный» пользователь потеряет возможность писать, «неугодная» точка зрения исчезнет. Жалко смотреть во что превратили карму.
На сколько я помню доступ из внешнего фрейма запрещен к внутреннему если домены различаются.
вот так всегда =) когда уже почти дописал сам — на хабре вылезает статья с готовым решением
Вообще-то, тема drag-and-drop'а файлов освещалась на хабре ещё год назад.
404
Спасибо, очень полезный комментарий. Могли бы и правильную ссылочку приложить.

(Единственная информация, которой я воспользовался для нахождения правильной ссылки — это адрес исходной. Что мешало Вам воспользоваться гуглом? Хотя бы так?)
Извините, вы приложили битую ссылку, я указал вам на это, и вы этим недовольны? Мне кажется, вы неправы.
Вы на даты постов вообще смотрели? Ссылка вполне работала тогда, когда я её постил. Или Вы считаете, что я должен постоянно проходить все свои посты, следя за свежестью ссылок? Извините тогда, но я не вижу в этом смысла.

А недоволен я бессмысленностью Вашего комментария. А если бы я не увидел Вашего комментария? Юзер, если ему интересна ссылка, и сам заметит, что она умерла. А вот приведи Вы рабочую ссылку, Вы бы сэкономили его время и силы.
А вот на даты-то я и не посмотрел. Да, тогда неправ я. Честно говоря, мне не пришло в голову искать нормальную ссылку, как-то на автомате… Не работает, что теперь с этим поделать.

По-моему, сложно его не увидеть. Не знаю, как у вас, а мне хабра даже на мыло оповещаловку шлёт.
Уведомления-то и мне приходят (откуда ж иначе я заметил бы Ваш комментарий), но их можно отключить или проигнорировать.
Хм, а мы с вами на javascript.ru не пересекались ранее?
Пересекались, конечно же :-)
Мир тесен, приятно встретиться)
С Dropbox'a лучше удалите, могут временно заблокировать за трафик

И маленькие опечатки… :)
> максимальный размер фалйа
> Скачать исходны-Е- файлы вы можете здесь.

Ну а за статью спасибо, ради интереса опробуем на досуге ;)
Спасибо, исправил опечатки.

А куда посоветуете закинуть файлы, что бы хабр аудитория была довольна? :)
Яндекс.Диск подойдёт. Или свой хост, аккаунт на Google сайтах. Чем прямее ссылка, тем лучше :)
Угу, поправил ссылку. Залил на Яндекс.Диск.
Картинки еще живы :)?
А зачем нужен заголовок X-FILE-NAME?
Если нужно передавать помимо файла другие значения, я бы посоветовал использовать FormData.
Если используется jQuery, то код, в первую очередь аяксовую часть, можно было бы написать проще. Если не используется — тоже: можно было бы использовать getElementById и иметь на выходе сразу нужный узел. А Вы почему-то его используете исключительно для усложнения кода.
Я лишь перевел статью, кое-где что-то дописав или исправив.

Я думаю автор не использовал jQuery AJAX из-за двух функций «uploadProgress» и «stateChange». И я думаю, здесь главное не то, каким образом тут используется jQuery, а просто показать принцип работы Drag and Drop. А то как вы его будете реализовывать это (на чистом JavaScript или при помощью сторонних библиотек) — это уже ваше решение.
Так вот я и говорю, что тогда уж использование jQuery из статьи стоило бы выбросить.
Кстати, в jQuery можно навешивать drag&drop обработчики событий. Так сделано в моей статье (которая на ту же тему как раз ;)
И почему большинство интересных штук придумывают за бугром?
Ну не скажите, я думаю у нас тоже есть чем гордится :)
У нас есть чем гордится, а «плюшки» придумывают всё равно за бугром.
Что здесь плохо, так это то, что при любом перемещении мыши с захваченным файлом над контейнером вы добавляете класс hover. При быстрых рывках мышью не наблюдается никаких артефактов?
Что будет, если я захвачу папку и брошу её?
> Что будет, если я захвачу папку и брошу её?
Ничего, массив files будет пустой, но можно выделить все файлы и перетащить их.

Довольно хорошая демка(да сам скрипт): aquantum-demo.appspot.com/file-upload
Обработчики на ondragover и ondragleave спокойно вешаются через jquery:
$('#dropZone').bind('dragover', function(event){...}).bind('ondragleave', function(event){...})

Раз файл передаются не как multipart запрос, то на стороне сервера массив $_FILES будет пустым и пример _не рабочий_, выхода 2:

1) использовать FormData
заменить:
xhr.send(file)
на:
var fd = new FormData
fd.append("file", file)
xhr.send(fd)


2) изменить серверную часть
$input = fopen("php://input", "r");
$target = fopen($path, "w");
$realSize = stream_copy_to_stream($input, $target);
fclose($input);
Несложно сделать выбор файла, добавив <input type="file" multiple="multiple" style="position:absolute;right:0;opacity:0;font-size:100px;"> в #dropZone:
$('#dropZone input').change(function(){
var file = this.files[0];
...
});
вариант с php://input, к сожалению, дико жрет память (3x размер загружаемого файла)
Можно поконкретней, когда и с чем это проявляется, попробовал на 250м файле, ни apache2, ни ff, ни chrome не стали есть значительно больше памяти после начала загрузи.

З. Ы. linux, загружал на localhost(возможно, не успевало буфферизоваться).
я на это напоролся в ходе использования скрипта fileuploader.js, который по сути делает то же, что в статье написано.
при загрузке мелких файлов все ок, при попытке залить файл на 200M php умирает из-за превышения memory_limit (стоял 512M).

собственно, содержание серверного скрипта роли вообще не играет, можно <?php echo memory_get_usage();?> в качестве upload.php поставить и посмотреть вживую.
при загрузке файла на 100K расход памяти где-то 400K, при загрузке 5.6M — уже 17M.

php5.3.6, apache2+mod_php, ось debian 6.0 / win7.

насколько я понимаю, проблема в том, что скрипт начинает исполняться только после полного получения тела запроса от клиента.
в случае обычного multipart/form-data php на ходу раскладывает все загружаемые файлы в свой upload_tmp_dir, и в $_FILES пишет только пути к ним, при нестандартной же кодировке запроса php не знает, что с ним делать и все тело висит в памяти.
вот зачем ему аж три копии — хз, в $HTTP_RAW_POST_DATA одна точно есть.
Провел еще раз эксперименты, процесс апача действительно съедает память, но если судить по top'у(ему я больше верю) — только в размере загружаемого файла, если по memory_get_usage(возващающему захваченную, но не факт что использованную память) — 3 размера файла, причем как с пустым скриптом так и с копированием php://input через stream_copy_to_stream
Спасибо, добрый человек. Всю голову сломал пока дошло, что стоит комменты прочитать. Автору поста — дислайк.
Спасибо за коммент!!!

Действительно помогло!!!

«maxFileSize = 1000000; // максимальный размер файла — 1 мб.» :)
maxFileSize = 1*1024*1024; поиллюстративнее будет.
Вообще говоря, 1 000 000 байтов — это действительно 1 мегабайт. 1 048 576 байтов — это уже 1 мебибайт, почти на 5% больше одного мегабайта.

ru.wikipedia.org/wiki/Мегабайт
А насколько хороша поддержка загрузки больших файлов.
Например 500MB с клиента потянет?
Я думаю потянет. Но вопрос есть ли смысл? Возможно, для загрузки больших фалов стоит использовать что-то другое. Я думаю вариант с Drag and Drop больше подходит для более мелких файлов, например для картинок и музыки.
D&D это всего лишь свойство контрола интерфейса, и в целом не имеет отношения к тому, как передается файл и что с ним вообще происходит.
И не всегда 500 мб через интеренет — это медленно.
Помимо самого D&D важен также способ отправки файлов. Стандартный XHR не умеет отправлять файлы (равно как и обычный JS даже не подозревает о существовании файлов), а стандарты пока находятся только в процессе разработки.
Так, например, в FF3.6 единственный способ отправить файл — отправить его содержимое в виде данных обычного (не multipart!) запроса (т.е. нужно получить весь файл одой строкой). Как результат — передать файл в 500мб, как минимум, затруднительно, т.к. чревато огромными затратами памяти.
Насчет FF3.6 вы немного ошибаетесь:

Starting with Gecko 1.9.2, you may also specify an DOM File

Т.е. начиная с FF3.6 (а это и есть Gecko 1.9.2) можно загружать файл не multipart-запросом, а просто содержимое файла в теле запроса, без чтения файла целиком в память.
Да, забыл про это.
Но это кривой способ, потому что файл на сервере нужно будет считывать из входного потока. Да и дополнительные параметры POST'ом не передать.
НЛО прилетело и опубликовало эту надпись здесь
Успех скорее зависит от «модности» темы поднятой в статье.
Не, реально модные пацаны сейчас пишут про то, как нарисовать на HTML Canvas треугольник с градиентом или его же, вращающимся на WebGL
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории