Xpoint
   [напомнить пароль]

Кроссбраузерный загрузчик данных без перезагрузки страницы

Метки: [без меток]
2005-01-27 01:18:02 [обр] Дмитрий Котеров(13/912)[досье]

Плод двух дней усиленного перебора вариантов (наверное, в сумме штук 20 способов было проверено, в совокупности со всеми их особенностями) представляю систему данных в браузер на страницу "на лету" без перезагрузки страницы и затирания history:

http://dklab.ru/chicken/nablas/demo/LiveLoader/t/
(вводите любую строку, получаете ее MD5-код, сгенерированный на сервере - кнопку нажимать не обязательно)

Сам JS тут: http://dklab.ru/chicken/nablas/demo/LiveLoader/ScriptLoader.js
Библиотека поддержки PHP: http://dklab.ru/chicken/nablas/demo/LiveLoader/ScriptLoader.phps
Простейший загрузчик выглядит так: http://dklab.ru/chicken/nablas/demo/LiveLoader/t/load.phps
(кстати, введя строчку "error", можно посмотреть, как оно срабатывает на фатальные ошибки в PHP)

Работает: в IE5+, FireFox, Opera 7.23.

Еще остается только сделать расшифровку JS escape() на PHP (там в юникоде данные приходят), но это уже детали.

Собственно, я чего тут пишу: хотелось бы попросить счастливых обладателей других браузеров протестировать это дело (интересует прежде всего Опера 7.0 и более старые). В IE 4.x можно сразу не проверять - там не работает DOM, насколько я понимаю. Значит, интересуют старые FireFox и Оперы.

Для любопытствующих сразу сообщаю, что метод не имеет ничего общего с тем. что применяется в Google Suggest, а также не использует IFRAME и ActiveX. Все - чистый DOM и JS.

спустя 1 час 22 минуты [обр] Давид Мзареулян(0/1003)[досье]
Динамическое создание SCRIPT-элемента? Вообще, идея занятная…
спустя 26 минут [обр] Дмитрий Котеров(13/912)[досье]
В принципе, можно еще и CSS-элементы динамически создавать. ;-) Только там данные передавать будет сложновато. Тут дело скорее даже не в занятности, а в безысходности - все остальные способы либо глючные, либо недостаточно кроссбраузерные.
спустя 2 часа 11 минут [обр] Алексей В. Иванов(25/2861)[досье]
Не работает в Opera 7.10 и 7.11. Старше версий не нашлось :)
спустя 5 часов [обр] Антон Иконников(24/30)[досье]
Mozilla Firebird 0.7 - работает.
спустя 23 минуты [обр] Дмитрий Донцов+++(1/68)[досье]

Дмитрий Котеров[досье]
Дмитрий, такой вопрос...
Когда просто устанавливаешь курсор в поле ввода, отсылается пустое значение (АА1.0 ШУ6)

на выходе имеем MD5('') = 'd41d8cd98f00b204e9800998ecf8427e'

так задумано?

спустя 4 часа 2 минуты [обр] Дмитрий Котеров(13/912)[досье]
Ну Вы сами-то посчитайте MD5 от пустоты, увидите, что оно столько и есть.
Но при чем тут?..
спустя 14 минут [обр] Дмитрий Донцов+++(1/68)[досье]
Дмитрий Котеров[досье]
вопрос не в md5 пустоты, а в отсылке пустого значения...
спустя 2 минуты [обр] Алексей В. Иванов(25/2861)[досье]
вопрос не в md5 пустоты, а в отсылке пустого значения...
Это все лишний треп. Не это обсуждается
спустя 1 час 28 минут [обр] Давид Мзареулян(0/1003)[досье]
Дмитрий Котеров[досье] А в чём тут бОльшая кроссбраузерность по сравнению, например, с iframe? Это не в наезд, мне и в самом деле Ваша идея нравится, но вот именно в плане кроссбраузерности я как-то решительных преимуществ не вижу.
спустя 5 часов [обр] Дмитрий Котеров(13/912)[досье]
  1. Через IFRAME не сделать без пачканья history. Вернее, сделать можно, но только через статические IFRAME (прописанные прямо в HTML-коде, вне JS-скрипта), через динамические - никак (проверено!).
  2. IFRAME щелкают при загрузке.
  3. IFRAME жрут кучу памяти (фактически, это отдельный полноценный браузер).
  4. У меня были проблемы с IFRAME в IE5 (уже сейчас не вспомню, какие).
В общем-то, насчет кроссбраузерности тут и правда маловато аргументов, но - тем не менее, только со SCRIPT удалось добиться кода, идентично работающего в таком обширном числе браузеров.
спустя 6 часов [обр] Дмитрий Котеров(13/912)[досье]

Новая версия, совместимая с XMLHttpRequest по интерфейсу.
http://dklab.ru/chicken/nablas/demo/JSHttpRequest/

Тестирование:
http://dklab.ru/chicken/nablas/demo/JSHttpRequest/t/test.htm

Новая идеология: все, что идет в STDOUT, попадает в окно debug (свойство responseText), а все, что присваивается PHP-массиву $_RESULT (можно делать многомерный), записывается в свойство responseJS. Это позволяет легко отлавливать ошибки в скрипте и забыть в PHP-загрузчиках такое страшное слово, как JavaScript. (Как и в прошлый раз, фатальная ошибка генерируется, если в строке запроса встречается слово error).

спустя 1 минуту [обр] Дмитрий Котеров(13/912)[досье]
Да, забыл сказать: для расшифровки escape()-данных из JS приходится применять iconv(). Да, из пушки по воробьям, но - я не вижу другого решения для IE 5.0.
спустя 7 часов [обр] Давид Мзареулян(0/1003)[досье]
Тема для статьи, однако.
спустя 5 дней [обр] Дмитрий Котеров(13/912)[досье]
А вот и статья:
http://dklab.ru/chicken/nablas/41.html
спустя 34 минуты [обр] Алексей В. Иванов(25/2861)[досье]

Дмитрий, прошу прощения, но это не серьезно:

Этому могут быть два объяснения: либо Google договорился с Microsoft считать свои обращения к Microsoft.XMLHTTP безопасными, либо же включается механизм, основанный на <IFRAME> (как в Opera).

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

спустя 20 часов [обр] Дмитрий Котеров(13/912)[досье]
Почему это "понятно"?
  1. Почему тогда не работает, если сохранить локальную копию Гугла на диске, и попробовать открыть?
  2. Почему не слышно щелчка при обновлении IFRAME?
спустя 5 минут [обр] Дмитрий Котеров(13/912)[досье]

Хотя, вообще-то, Вы правы, вероятно. Есть же Проксомитрон. Удалил им тэг IFRAME и убедился, что работать перестало (Гугл начал перезагружать сам себя). Статью сейчас поправлю.

Тогда непонятно, коли они все равно сделали через IFRAME, зачем было городить огород с Microsoft.XMLHTTP и XMLHttpRequest.

спустя 1 час 33 минуты [обр] Владимир Палант(4/4445)[досье]
Потому что XMLHttpRequest для этого предназначен и даёт максимум удобств. iframe — костыль для Оперы и "безопасного" IE.
спустя 11 часов [обр] Давид Мзареулян(0/1003)[досье]
А не хотите ли пополнить вот эту страницу?
спустя 3 часа 40 минут [обр] Дмитрий Котеров(13/912)[досье]

Ну пополнил...

(Все-таки, надо WYSIWYG-редактор для wiki. Бороться с этими WikiNames, вставляемыми к месту и не к месту, сил никаких нет. Неюзабельно страшно, желание что-то пополнять после всех ковыряний улетучивается очень быстро.)

спустя 14 минут [обр] Евгений Бондарев aka Eugene Bond(2/1600)[досье]
Дмитрий Котеров[досье]
Да.. Это не phpBB....
спустя 14 минут [обр] Давид Мзареулян(0/1003)[досье]
Юзайте тильду (~ActiveX) и будет Вам счастье…
спустя 1 час 31 минуту [обр] Дмитрий Котеров(13/912)[досье]

В phpBB тоже бы не помешал WYSIWYG. Он бы, видимо, вообще никому и нигде не помешал. ;-) Но wiki все же - в первую очередь. Особенно неудобно, когда хочется поправить большую страницу в одном-единственном месте (опечатку исправить, например), и приходится из-за этого елозить по textarea в поисках слова, подлежащего изменению.

Впрочем, это все оффтопик. Тему, думаю, можно закрывать.

спустя 18 часов [обр] Давид Мзареулян(0/1003)[досье]

Вообще, я имел в виду, что пан мог бы изложить суть метода и непосредственно в вике, поскольку там писанины на два абзаца от силы. Ну да ладно.

Что меня до сих пор слегка настораживает. При каждом обращении к серверу создаётся новый элемент SCRIPT. Обращений может быть много. Например, страница може периодически что-то запрашивать с сервера. Как отреагирует браузер на действительно большое количество SCRIPT-элементов? Пробовал ли пан менять src динамически у существующего элемента SCRIPT и возможно ли это вообще?

По набле: «Живая карма» такой тяжёлой артиллерии не требует, кода 204 достаточно.

спустя 1 час 53 минуты [обр] Дмитрий Котеров(13/912)[досье]
  1. Что еще за "пан" такой?
  2. Зачем 2 раза писать одно и то же? А вдруг придется вносить изменения? Что, в двух местах править?
  3. Изменять src - можно, но не везде работает.
  4. Проблем со скоростью пока не наблюдал, хотя больше 20-30 загрузок на страницу не делал, это верно (пусть "обратная связь" тестирует, нужна же она для чего-то). К тому же - там лишние <script>-тэги потом удаляются после загрузки (правда, я не уверен, что при этом память освобождается, все зависит от браузера).
  5. 204 нельзя, потому что при обрыве связи бьется текущая страница. На примере orphus.ru было доказано, что это очень частое явление. Можно - в невидимый iframe писать, это да, но - какой смысл, когда есть динамическая подгрузка?
Короче говоря, "В ЦК не дураки сидят! Вы ночью полетите."
спустя 21 день [обр] Соловьев Максим aka Adept(0/3)[досье]
Дмитрий Котеров[досье]
Посмотрите демку компонента от obout.com — выполняет примерно тоже самое
спустя 15 часов [обр] Дмитрий Котеров(13/912)[досье]
Вот эту? http://www.obout.com/obout/treeview/sample/xp_web_main.asp
Ну, что могу сказать... Во-первых, Опера отдыхает. Во-вторых, IE с отключенными ActiveX тоже отдыхает. Так что тут даже не "примерно" то же самое, к сожалению...
спустя 5 часов [обр] Соловьев Максим aka Adept(0/3)[досье]
спустя 6 часов [обр] Дмитрий Котеров(13/912)[досье]
То же самое замечание.
спустя 1 месяц [обр] Даниэль Алиевский(0/125)[досье]

Дмитрий Котеров[досье]
Приветствую! Посмотрел вашу статью http://dklab.ru/chicken/nablas/41.html

Любопытно. Но мне бросилась в глаза ваша оговорка:

...в FireFox имеется небольшая ошибка, в результате которой статус-строка не очищается после загрузки <SCRIPT>-компонента (в ней остается сообщение "Loading ..."). Впрочем, эта ошибка ни на что не влияет и, вероятно, будет в скором времени исправлена разработчиками.

Кому как, а мне эта ошибка не показалась "небольшой". Я иногда использую медленный (зато дешевый) канал, и подобная надпись в статусе очень сбивает с толку. Вы как-либо сообщили об этой ошибке авторам FireFox?

Что до самого метода: я рад, что он работает надежно. Но решение гугла мне как-то больше по душе. Ваш вариант имеет что-то общее с трюкачеством. По замыслу, тег script явно не предназначен для динамической подгрузки данных с сервера, а служит для написания JavaScript-библиотек. Средства же типа Msxml2.XMLHTTP и XMLHttpRequest, насколько я понимаю, специально созданы для решения поставленной задачи. Зачем забивать гвозди универсальным, очень качественным (увесистым и кроссбраузерным) микроскопом, когда есть молоток? Или даже 2 несовместимых молотка и один здоровенный топор (IFRAME)? Я уже не говорю о необходимости обязательно представлять желаемые данные в виде JavaScript-кода...

Пусть даже вы сейчас и добились работы под всеми броузерами, но почему вы уверены, что лет через 5 (когда вы уже, например, давно потеряете интерес к данной библиотеке или к программированию вообще) Microsoft не вздумает иначе отрабатывать динамически созданные script-ы? Или вовсе не запретит их по умолчанию? Могу обратить внимание на проблемы с динамическими скриптами, описанные здесь: document.writeln('<scr'+'ipt src=...'> и выползание контента из контейнера В отличие от вас, мне "не повезло".

А вот средство, придуманное самим Microsoft, вероятнее всего, будет продолжать работать как задумано. То же самое касается XMLHttpRequest.

Недостатки же подхода Google, упомянутые вами, мне кажутся не очень важными.

  1. Ну да, ActiveX должны быть включены - и это так, кажется, у 99% пользователей MSIE. А если пользователь их вручную выключил - что же плохого в том, что функциональность сайта снизится? Это как раз логично. Вероятно, посетитель больше пострадает от отсутствия MacroMedia, чем от потери хитрой подгрузки данных. В конце концов, JavaScript тоже можно отключить (с теми же целями безопасности). При всем при этом, ведь остается "топорный" IFRAME.
  2. Насчет XMLHttpRequest, который не может загружать данные с чужих сайтов - вот и слава богу. Это не недостаток, а разумная политика безопасности. А разве ваш JavaScript имеет смысл загружать с "левых" сайтов?
  3. IFRAME с его щелчками и порчей history - и правда не очень приятно. Но лично мне порча строки статуса под FireFox кажется куда менее приятной. Подумаешь, щелчки какие-то... Кстати, а под Opera (единственным броузером, где это нужно, не считая MSIE с отключенными ActiveX) IFRAME тоже щелкает и портит history?

В конце концов, под всеми известными версиями броузеров, для которых ваш метод заведомо работает, но не работают Msxml2.XMLHTTP и XMLHttpRequest, ваша библиотека может быть подходящим решением. (А для неизвестных остается IFRAME.) Мне не нравится только применение вашего подхода как универсального решения, достаточного для применения в законченных сайтах.

спустя 6 часов [обр] Дмитрий Котеров(13/912)[досье]
  1. Отключение ActiveX, действительно, приводит к неработоспособности Flash. Я этого никогда, честно говоря, не понимал. Что вообще значит "ActiveX включены"? Насколько это снижает безопасность? Какие компоненты ActiveX разрешено запускать, а какие - нет?
  2. У меня так в статье сделано - грузятся результаты поиска в форуме (правда, для демонстрации).
  3. Кажется, везде. Но Вы не совсем, наверное, поняли. Порча history на некоторых сайтах просто недопустима. Например, на форуме - люди очень часто нажимают back, когда просматривают один топик за другим. Это естественно. И, когда у меня был предпросмотр на IFRAME сделан, тут же поступила куча жалоб.
Что касается скриптов. Во всех языках программирования одна библиотека может подключать другие. Во всех, кроме JavaScript - там почему-то оператора включения кода нет. Это очень глупо, как мне кажется. Несколько лет назад, когда я спросил, а как же, собственно, быть, мне как раз и посоветовали способ с динамическим созданием (или реюзингом) тэга <SCRIPT> и присвоемнием src в нем адреса скрипта.
спустя 3 дня [обр] Даниэль Алиевский(0/125)[досье]

Дмитрий Котеров[досье]

  1. Идея Microsoft с ActiveX вообще дурная, как показала практика. Почти 100% вирусов и spyware в баннерных сетях распространяется именно за счет того, что посетителю популярно объясняют, порой с помощью flash-мультика, что именно следует сделать, чтобы инсталлировался их вирусный ActiveX! В виде инструкции для чайника: "вы видите это, жмите сюда, и вам будет хорошо". Смешно :-)
  1. Ну тогда может быть. А Google как решает эту проблему под Opera? Или ему не важно?
Что касается скриптов. Во всех языках программирования одна библиотека может подключать другие. Во всех, кроме JavaScript - там почему-то оператора включения кода нет. Это очень глупо, как мне кажется.

Ну все-таки кесарю кесарево. Я думаю, что ограничения подобного рода для JavaScript вполне оправданы. На том же Perl или PHP, как правило, пишут серверные программисты, т.е. не совсем чайники. Сервер - дело ответственное. А JavaScript создан для украшения HTML-страниц, которые пишут все, кому не лень. Примерно как Flash. Причем именно для украшения - хорошим тоном считается, если страница работает и без JavaScript. Более того, JavaScript всегда скачивается к клиенту и влияет тем самым на "вес" страницы. Ergo, 99.99% программ на JavaScript должны быть маленькими и несложными. И к этому отсутствие модульности поощряет. Для 0.01% необычных ситуаций (вроде google) остаются всякие нестандартные приемы.

С другой стороны. А что такого плохого в необходимости явно указать список подключаемых js-модулей в HTML-странице? Вспомните старые компиляторы: там тоже надо было вызвать линковщик, явно перечислив требуемые библиотеки. По-моему, ситуация похожая. И ничего, таким образом создавались громадные проекты.

Несколько лет назад, когда я спросил, а как же, собственно, быть, мне как раз и посоветовали способ с динамическим созданием (или реюзингом) тэга <SCRIPT> и присвоемнием src в нем адреса скрипта.

А вот это, извините, все же несколько иное. Это позднее связывание при подключении библиотеки, когда требуемая библиотека неизвестна "на этапе компиляции" (при написании набора <script src=...> в HTML-коде). Да, многие современные языки/платформы это позволяют (скажем, рефлексия в Java или динамическая подгрузка DLL в WinAPI), но повседневной практикой это никак не назовешь.

Причем в "нормальных" языках эта практика все же документирована. А вы можете показать стандарт, регламентирующий описанное применение тега SCRIPT? (Извините, если это уже было в статье, а я не заметил.)

спустя 11 часов [обр] Дмитрий Котеров(13/912)[досье]
Стандарт показать, увы, не могу - действовал методом проб и ошибок, выбирая единственный рабочий вариант.
спустя 9 дней [обр] Давид Мзареулян(0/1003)[досье]

Юзаю Вашу библиотеку. Сильно нравится. Респект. Пара замечаний:

В PHP-части:

  function _php2js($a)
  {
    if (is_null($a)) return 'null';
    if ($a === false) return 'false';
    if ($a === true) return 'true';
    /** начало изменения **/
    if (is_int($a) or is_float($a)) {
      return "$a";
    } elseif (is_scalar($a)) {
    /** конец изменения **/
      $a = addslashes($a);
      $a = str_replace("\n", '\n', $a);
      ...

Сильно облегчает ж.

В JS-части: все onreadystatechange(); заменить на if(onreadystatechange) onreadystatechange();. Потому что бывает и такое, да.

спустя 11 часов [обр] Дмитрий Котеров(13/912)[досье]
Внес изменения. Только лучше бы Вы вот сюда писали:
http://forum.dklab.ru/comments......aWithoutPerezagruzkiPages.html
Это официальный топик библиотеки.
спустя 2 часа [обр] Давид Мзареулян(0/1003)[досье]
Ну, там регистрироваться надо, то-сё…
спустя 1 час 33 минуты [обр] Дмитрий Котеров(13/912)[досье]
Давид, Вы что клевещете? Не надо там регистрироваться, и нигде на форуме не надо.
спустя 47 минут [обр] Давид Мзареулян(0/1003)[досье]
Хм. И в самом деле… а куда же я нажимал тогда, что у меня пароль спрашивали?
А! Я на «новую тему» нажимал!
спустя 1 час 43 минуты [обр] Дмитрий Котеров(13/912)[досье]
Новые темы в форуме, посвященном наблам, запрещено создавать. :-)
В общем, чтобы прекратить оффтопик, предлагаю данный топик закрыть и поместить в архив.
спустя 2 дня 18 часов [обр] LookeR(275/1069)[досье]
М А действительно тему надо в Архив? В ней есть что-то достойное всеобщего внимания?
спустя 55 минут [обр] Даниэль Алиевский(0/125)[досье]
LookeR[досье] IMHO стирать ее не надо, ибо это реклама интересного продукта одновременно с его критикой :-) Читателям пригодится.
спустя 7 часов [обр] Rom McRitsky(0/441)[досье]
Есть по крайней мерре ссылка на обсуждение :)
спустя 3 часа 2 минуты [обр] Даниэль Алиевский(0/125)[досье]
Нечаянно заглянул и заметил, что вроде как и Опера теперь поддержала XMLHttpRequest:
http://xpoint.ru/news/item.xhtml?id=155
Вряд ли, впрочем, подобной милости дождемся от Microsoft.
спустя 3 дня [обр] Соловьев Максим aka Adept(0/3)[досье]

Даниэль Алиевский[досье]
На одном из блогов недавно разработчики IE 7.0 писали, что они пошли навстречу своим клиентам — веб-разработчикам. А вдруг...

http://blogs.msdn.com/ie/archive/2005/03/09/391362.aspx

Microsoft does respond to customer demand; web developers are our customers.
спустя 2 часа [обр] Владимир Палант(4/4445)[досье]
Они никогда не откажутся от ActiveX, он слишком важен для них в стратегическом плане.
спустя 1 месяц 1 день [обр] Соловьев Максим aka Adept(0/3)[досье]
Владимир Палант[досье]
Пусть просто стандарты реализуют в своих продуктах :)
спустя 12 часов [обр] Иван Шумков(0/77)[досье]
Это ошибка или фича, но при подгрузки данных в IE срабатывает window.onresize. Это зачем?
спустя 2 дня 8 часов [обр] Дмитрий Котеров(13/912)[досье]
Баг IE?
спустя 2 часа 20 минут [обр] Иван Шумков(0/77)[досье]
Дмитрий Котеров[досье]
Не знаю. Каждый раз срабатывает в IE 6.0 WinXp Sp2.
Срабатывает имеено в момент когда данные загружены.
Powered by POEM™ Engine Copyright © 2002-2005