Есть трюк, древний как мир. Называется "ajax file upload" и заключается в отправке файла на сервер без всякого аякса, а очень тупым способом, через динамически создаваемую форму и submit ее в iframe. Всегда работало, а тут сломалось. Ну, как сломалось, так и починилось, и писать не стоит, если бы не один фантастически смешной аспект поведения IE.
Итак, на дворе 2013 год, кругом HTML5, FileAPI и прочие чудеса техники. Это с одной стороны. А с другой - субмит в ифрейм и старый добрый ИЕ10 (на других не тестил).
Имеем нехитрый код:
// отправить поле file_input на сервер аяксом
function ajax_file_upload(file_input) {
// создаем форму с target="ifr"
var $f =
$('<form action="" method="post" target="ifr" enctype="multipart/form-data">'+
'<input type="submit" />'+
'</form>');
// вставляем в нее input
$f.append($(file_input));
// вставляем форму в body
$('body').append($f);
// создаем ифрейм
$('body').append('<iframe name="ifr" />');
// отправляем форму
var f = $f.get(0);
f.submit();
}
Все предельно тупо. На самом деле это сокращенное содержание известной библиотечки jQuery AjaxFileUpload. Далее вешаем на change нашего <input type="file" /> вызов этой штуки и все ок.
Все ок, пока мы не решаем вместо уродливого инпута забабахать красивую кнопку. Дело привычное, инпут скрываем, а по клику на кнопке генерим клик по инпуту. Обработчики выглядят так:
// клик по кнопке
$('#coolbutton').click(function() {
$('#fileinp').click();
});
// выбор файла
$('#fileinp').change( function() {
ajax_file_upload(this);
});
Везде работает, в ИЕ дохнет. Ностальжи )) Путем бубна и замысловатых ругательств заменяю последнюю строчку метода ajax_file_upload на вот такую конструкцию:
try {
f.submit();
console.log('submit 1 ok');
} catch (e) {
console.log('submit 1 failed: '+e );
try {
f.submit();
console.log('submit 2 ok');
} catch (e2) {
console.log('submit 2 failed: '+e2 );
try {
f.submit();
console.log('submit 3 ok');
} catch (e3) {
console.log('submit 3 failed: '+e3 );
}
}
}
Идиотский код, не правда ли? Как вы думаете, что будет в консоли? А вот что:
submit 1 failed: Error: Отказано в доступе.
submit 2 failed: Error: Отказано в доступе.
submit 3 ok
Зрители аплодируют. Я великий хакер.
Кто-нибудь объяснит мне, что происходит?
Выкладываю полный кликабельный пример и его исходник. Расскажите, у кого какой результат в каком ИЕ? Там можно жать на инпут (тогда у меня срабатывает "subit 1 ok") и на ссылку (тогда с третьего раза, как выше).