barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

вторник, 17 января 2012 г.

iframe onLoad и загрузка файлов

Проблема:
Используется скрытый iframe для загрузки файлов (из JS устанавливается src заданного в html-разметке iframe`а равным URL`у, по которому сервер выдает необходимый файл). Необходимо после ответа сервера (когда браузер открывает окно сохранения файла) вызвать callback-функцию. Проблема заключается в том, что если содержимое iframe не является html-ем (точнее, Content-Type заголовок является таковым, что браузер открывает окно сохранения), событие onLoad не срабатывает (по крайней мере в Firefox, в IE однако все ок).

Решение:
Вместо динамической установки src iframe`а создавать iframe каждый раз заново, тогда onLoad срабатывает:
document.getElementById("reportLoadIframeDiv").innerHTML = '<iframe src="getFileServlet" onload="myCallback()"></iframe>';
Видимо, загрузка файла в iframe не вызывает onLoad только при повторной загрузке iframe (т.к. при задании iframe html`ем он сначала загружается с пустым src, и его загрузка после динамической установки src является уже повторной). При приведенном выше подходе iframe каждый раз - новый, и при первой же своей загрузке он выдает нам файл.
Однако, приведенный выше код теперь не работает в IE: событие onload в таком случае не происходит (тогда как при статичном iframe все работало). Спасает специфичное для IE событие "onreadystatechange", оно вызывается в любом случае, даже при загрузке файла:
document.getElementById("reportLoadIframeDiv").innerHTML = '<iframe src="getFileServlet" onload="myCallback()" onreadystatechange="myCallback()"></iframe>';
 При таком подходе в FF вызовется обработчик onload, в IE - onreadystatechange.


В общем, выводы из вышеописанного такие:
  1. При статичном задании iframe с обработчиком onLoad в HTML-коде при динамическом изменении src и последующей загрузке файла в этот iframe обработчик не вызывается в Firefox, но вызывается в IE
  2. При динамическом создании iframe с необходимым для загрузки файла src обработчик onLoad вызывается в Firefox и не вызывается в IE (причем в IE он не вызывается, даже если в iframe загружается не файл, а просто HTML)
  3. При динамическом создании iframe при его загрузке в IE всегда вызывается onreadystatechange, независимо от того, что загружается в iframe, файл или html. При этом в Firefox данный обработчик всегда игнорируется.

2 комментария:

  1. Спасибо за ценную инфу! Полдня билась с IE9, пока не нашла вашу заметку :)

    ОтветитьУдалить
    Ответы
    1. Пожалуйста! Всегда рад, когда мои заметки помогают кому-то =)

      Удалить