Я решаю эту задачу через скрытый iframe.
Код:
<form style="overflow:hidden;height:0;width:0;" id="uploadForm" action="/uploadfile/" method="post" enctype="multipart/form-data" target="uploadFrame">
<input type="text" name="path" value="/" />
<input type="file" name="file" multiple="false" />
</form>
<iframe style="border:none;height:0;width:0;" id="uploadFrame" name="uploadFrame"></iframe>
<script>
window.currentPath = '/';
function doFileUpload(){
if (jQuery('#uploadForm input[name="file"]').val() == '') return;
jQuery('#uploadForm input[name="path"]').val(window.currentPath);
jQuery('#uploadForm').submit();
// ЗДЕСЬ ВСТАВЛЯЕМ КОД, КОТОРЫЙ ПОКАЖЕТ ГДЕ-НИБУДЬ АНИМАШКУ ЗАГРУЗКИ
}
function uploadFrameLoad(){
var response = jQuery('#uploadFrame').contents().find('body').html();
jQuery('#uploadForm input[name="file"]').val('');
// УБИРАЕМ АНИМАШКУ ЗАГРУЗКИ, И ПАРСИМ ИМЕНА ФАЙЛИКОВ, ПОЛУЧЕННЫХ В ПЕРЕМЕННУЮ response
}
jQuery(window).load(function(){
jQuery('#uploadFrame').on('load',uploadFrameLoad);
jQuery('#uploadForm input[name="file"]').change(doFileUpload);
});
</script>
Форма и фрейм видимы, но имеют нулевой размер, чтобы не разъезжать вёрстку, но при этом обойти браузерную "секурную" фишку со скрытыми инпутами и фреймами.
Чтобы вызвать диалог выбора файлов, нужно выполнить:
Код:
jQuery('#uploadForm input[name="file"]').click();
Это сымитирует клик
* по инпуту типа "файл" в форме, вызывая нормальную его реакцию. После того, как его контент изменится (файлики выбраны) форма засабмиттится во фрейм, и как она прогрузится, контент (читай - имена загруженных файлов) будут в переменной
response в функции uploadFrameLoad().
Как бы просто всё. Но пришёл я к этому варианту не сразу - пришлось повоевать с браузерами. (:
* Этот код работает в последних версиях браузеров. Ещё на этапе эволюции этого метода, для IE8 приходилось не вызывать метод jQuery(...).click(), а нативно инвокать ивент, переданный в обработчик, на инпуте, как бы передавая реально сгенерированный клик.