Pull to refresh

Comments 32

Вы бы хоть демо, код или исходники показали. А то одна вода.
Ну это же не инструкция или HowTo для начинающих, а вспомогательный материал указывающий, где именно могут быть подводные камни. Я даже не претендую на то, что мои решения были самыми правильными. Однако они работают

Простейший код скрыт за словесными конструкциями. Например:
«нужно обрамить отображаемый frame в невидимый div (display: none)» следует понимать как "<div style="display: none"><frame>...</frame></div>"
Ну это же не инструкция или HowTo для начинающих

Учитывая количество багов полученное после «окончания тестирования» и начала продакшн эксплуатации, я могу предположить что реализацией занимались как раз таки «начинающие».
И вообще зачем эти костыли с установкой action формы в имя фрейма? У формы уже тысячу лет есть аттрибут target в который надо записать id iframe-а. А в iframe надо не json возвращять, а

<html>
  <head>
    <script type="text/javascript">
      window.parent.showUploadedImages(["file1.jpg","..",...]);
    </script>
  </head>
  <body>
  </body>
</head>
</html>


И ничего парсить не прейдеться. Плюс соответственно надо реализовать в основном окне функцию showUploadedImages

Но это все тоже для «начинающих», в обще лучше использовать plupload который позволяет реализовать:
— Chunking
— Drag/Drop
— PNG Resize
— JPEG Resize
— Type filtering
— Stream upload
— Multipart upload
— File size restriction
— Upload progress

и объединяет в себе следующие способы загрузки:
— Flash
— Gears
— HTML 5
— Silverlight
— BrowserPlus
— HTML 4

При этом plupload позволяет делать resize изображения еще на стороне клиента, тем самым разгружая сервер.
> Одной из самых неприятных проблем было то, что не всегда корректно срабатывает
> отправление на сервер пересекающийся форм (например, форма в форме).
А вы в курсе, что по стандартам это недопустимо?
В курсе. И пришлось решить данную проблему в соответствии со стандартом
iframe можно еще скрыть с position:absolute; left:-1000px;top:-1000px;
Как насчёт кроссбраузерности? Точно не помню, но по-моему в каком-то браузере косячило
А что тут не так с кроссбраузерностью?
Если сайт использует jquery, то поможет code.google.com/p/ocupload/
Мы от собственного решения перешли на него в свое время.
Ещё один подводный камень связан с обработкой ошибок. Если скрипт, который принимает аплоад, упадёт с ошибкой, то скрипт формы об этом не узнает. Решается перехватом всех-всех-всех исключений в обработчике аплоада на сервере, и в случае проблем возвращает 200 OK с сообщением об ошибке.
Абсолютно все исключения, к сожалению, не перехватишь :( Например, если сервер физически вырубили шваброй — то ближайшие пару минут он уже точно ничего не вернет. А JS часть должна уметь обрабатывать и такие проблемы
Это факт. Вы научились их обрабатывать?
Таймер… Если полоска прогресса не двигается больше определённого времени, то на сервер высылается лог об ошибке, а JS-часть пытается переотправить файл. Физически его будет принимать уже другой сервер
Я сейчас с этим мучаюсь. Решил бомбежкой скрытого фрейма через каждые 100мс с попыткой получения доступа к документу фрейма. Если доступ к документу (или body внекоторых браузерах) падает с ошибкой доступа — сервер прислал ошибку или вообще лег.
А зачем этот геморой? Существует милион решений. uploadify Например. Гиперудобная вещь. И т.д. и т.п.
1) JQuery. У нас не используется
2) Готовые модули намного тяжелее тесно интегрировать в свои скрипты. Так же чтобы оптимизировать нагрузку в них надо хорошо разбираться
uploadify, если помнится, загружает файлы через флешь, что само по себе в данном конкретном случае сильное усложнение.
Странненько, буквально вот недавно писал точно такую же лабуду, которая просто вешается на определённый элемент, с возможностью передачи дополнительных параметров. Всё создаётся динамически и iframe и форма, при этом после работы это же всё вычищается… хотя можно и подумать над тем чтобы оставлять, для дальнейшего использования (надо записать где-то :)).

И судя по тому что отзывов по поводу неработоспособности нет, то пока всё тьфу-тьфу-тьфу.
А что если на странице потребуется, ну допустим, 30 кнопочек «загрузить изображение»(это может быть в комментах, в футере, хедере, в левом столбце и т.д. и т.п.)… Реально такое может понадобиться…

Работать будет?
Если фрейм один — то нет.
Если фрейм один — то одновременная загрузка не будет работать (по очереди — будет). У нас фрейм вынесен прямо в шаблон с html-кодом загрузчика. Каждому загрузчику свой фрейм
А вы знаете, что более 6-10 потоков браузер не обрабатывает? Вопрос с 30-ю кнопочками не просто так задавался…
Нет, не пробовал. Тем более у нас стоит лимит на количество изображений (6 штук) + на их размер. Так что реально одновременно будут загружаться не больше 6 изображений
ну хорошо, реальные тесты были с 6ю фреймами?

но больше меня интересует другое… все и вся пытаются всё сделать динамичным… здесь вы предлагаете аяксом картинки грузить, кто-то comet серверы изобретают, ну и т.д… Тестировалось ли это совместно? Какие результаты? Какие проблемы и пути их решения?
Comet сервер не пробовал. А нас стоит nginx. На аякс загрузку после исправления глюков никто не жаловался
кайкой браузер обрабатывает 6-10 потоков? откуда такие цифры?
Цифры?

developer.mozilla.org/en/Mozilla_Networking_Preferences
Смотрим параметр network.http.max-persistent-connections-per-server = 8

У остальных браузеров примерно одинаковые цифры. А вообще часто сами операционки ограничивают количество одновременных http-соединений (в XP такое было точно)
ааа вон о чём речь… ну тут я проблемы не вижу… это ж с какой надо скоростью мышкой кликать чтоб больше 8 картинок параллельно отправить на сервер… 30 штук на одной странице это всего лишь юзерфрендли, а не распараллеливание…

больше интересует как обойти политики безопасности в разных браузерах… например IE6-7 при 2х iframe'ах после 2 — 3го клика на сайте врубают блокировку и например при обращении к document.location.hash или document.location.protocol получаем ACCESS DENIED… В других браузерах тоже начинаются свои косяки… только в Firefox начиная с 4й версии боле-менее всё стало лояльно…

как автор статьи решал данные проблемы?
Не нужно их обходить, не давайте пользователю работать напрямую с iframe, переносите содержимое в тело основной страницы. За 4 года работы по такой схеме ни один клиент не жаловался.
Впечатление от статьи резко отрицательное. Такое ощущение, что вы вместо того, чтобы почитать хорошую статью/стандарт/quirksmode, делаете все наугад, а потом ругаетесь, что не работает: «не всегда корректно срабатывает отправление на сервер пересекающийся форм (например, форма в форме)» — нельзя делать форму в форме вообще-то!

Ну и эти цитаты тоже чего стоят:

> Устанавливаем action формы в имя фрейма.

> Как оказалось, это известный баг — при изменении DOM-дерева в IE7 вызывается onChange. В нём JS-код изменяет структуру HTML-документа. Это опять вызывает onChange.

Я подозреваю, вы куда-то пытались перенести в дереве File Input, файл в нем сбрасывался и срабатывал onchange — это нельзя считать багом МС, а багом разработчика.

> Т.е. получается race condition и IE7 просто игнорирует изменения и посылает пустое имя файла.

Вы хоть в википедии почитайте, что такое race condition…

> Дело в том, что JSON-ответ от сервера приходится передавать с mime-типом text/html, а не application/json. При попытке открыть в iframe данные с типом application/json некоторые браузеры предлагали пользователю скачать бинарный файл, в то время как он должен втихую обрабатываться в JavaScript.

Не должны они обрабатываться, Опера все делает правильно.

— Добавлю еще по своему опыту загрузки через iframe: поскольку File Input сабмитится в ифрейм отдельно от остальной формы (которая сабмитится как обычная форма), то необходимо размещать его в дереве DOM в отдельной форме. Это может быть сложно, если выше и ниже инпута поля «обычной» формы. Решения тут 2: (более сложное но более правильное) — разместить форму с инпутом до/после основной и спозиционировать инпут средствами CSS (position: relative например) и (корявое, некрасивое) — вставить в основную форму ифрейм, в него File Input и скрытый фрейм. Получается нелогично и несеманично, но это работает, если например в форму динамиечски добавляются поля и инпут с файлом должен сдвигаться вниз.

Печально, что HTML ничего не предлагает (HTML 5 вроде начал предлагать File API и еще что то там) для
асинхронной загрузки файлов с докачкой.

Второй момент — трудно обнаружить ошибки загрузки файла в ифрейм, например из-за разрыва соединения, так как нет события ошибки. Можно ловить событие onload ифрейма, но оно не сработает, если загрузка по каким-то причинам замедлилась до очень низкой скорости или остановилась. Особенно трудно, когда файл надо загружать на сторонний сайт (например, ютуб). На своем сайте можно периодически аяксом спрашивать состояние загрузки, а на чужом — никак.
>Я подозреваю, вы куда-то пытались перенести в дереве File Input

Не правильно подозреваете. Возможно, я не корректно высказался. Race condition там происходит из-за рекурсивного вызова обработчика onChange. File input изменился — вызвался onChange. В onChange произошло считывание значение input'a. Ie7 думает, что input опять изменился. Опять вызывает onChange

>Вы хоть в википедии почитайте, что такое race condition…
Угу, и про железнодорожные семафоры там же почитать? Работал, знаю

>Не должны они обрабатываться, Опера все делает правильно.
Вот именно, что не должны. Тем не менее в логе была изменённая строка. А в ней base64 закодирование изображение «Подождите, загрузка»…

>то необходимо размещать его в дереве DOM в отдельной форме
Ага. Этим и занимаюсь позже, динамически таская его по DOM-дереву

>трудно обнаружить ошибки загрузки файла в ифрейм
Это точно. Кроме таймер так ничего и не придумал. Хорошо хоть всё на своём сайте и в запросах не ограничен…
Sign up to leave a comment.

Articles