Бесконечный IFrame - одна из основ ранних, да и современных AJAX-приложений. В этом транспорте - больше всего тонкостей (естественно, это ж хак оконного интерфейса! , которые я постарался раскрыть и продемонстрировать в этой статье.
Способ основан на том, что браузер обрабатывает страницу последовательно и обрабатывает все новые теги по мере того, как сервер их присылает.
Классическая реализация - это когда клиент создает невидимый IFrame, ведущий на служебный URL. Сервер, получив соединение на этот URL, не закрывает его, а
время от времени присылает блоки сообщений <script>...javascript...</script>. Появившийся в IFrame'е javascript тут же выполняется браузером, передавая информацию на основную страницу.
Таким образом, для передачи данных используется "бесконечный" ифрейм, через который сервер присылает все новые данные. Этот способ самый известный и кросс-браузерный.
Некоторые версии IE не начинают выполнять javascript, пока страница не достигнет определенного размера. Поэтому первые несколько сообщений задерживаются, т.к браузер ждет, пока ифрейм подрастет.
Решение - забить начало ифрейма чем-нибудь, поставить, например, 1К пробелов в начале.
Процесс Server push должен происходить по возможности незаметно от пользователя, которого нужно уведомлять только при появлении соответствующих событий.
А натура IFrame, наоборот, сопровождается индикацией: курсор-часики, полоса загрузки, и т.п. Наиболее отчетливо эта проблема была видна в IE6 до определенной версии, где индикатор прогресса слишком ярко анимировался и привлекал внимание.
Решение проблемы индикации для транспорта iframe Вы найдете в статье AJAX-транспорт IFrame.
Клиентский код - еще проще. Каждое сообщение оборачивается в span и добавляется через DOM к диву.
function handleDigit(digit) {
var s = document.createElement('span')
s.innerHTML = digit+' '
document.getElementById('endless_frame_div').appendChild(s)
}
В общем виде недостатки и достоинства можно перечислить как
минимальная задержка и трафик
данные нельзя сжимать
ряд технических и визуальных проблем из-за хакерской природы транспорта iframe
Отсутствие трафика заголовков и задержек дают возможность, например, отображать задержку до пользователя (лаг).
Для этого каждую секунду (или несколько) - на сервер создается событие типа "я тут, время XXX". Javascript на клиенте, получив это сообщение, сравнивает время со своим, локальным (оба времени GMT) и выводит разницу как лаг.
Кроме того, на onload-событие iframe (window.onload) обычно вешают обработчик. Конец загрузки iframe означает разрыв связи с сервером, поэтому такой обработчик вызывает функцию disconnect основного окна.
Вы можете скачать исходник кросс-браузерного бесконечного iframe в конце статьи AJAX-транспорт IFrame.
Илья, для того, чтобы не было эффектов в статусбаре, можно iframe-загрузчик поместить в другой iframe-обертку, у которого src пустой, а для IE нужно указать в iframe-обертке
Вот код создания iframe - по сути, код некоторой функции connect:
if (navigator.appVersion.indexOf("MSIE") != -1)
{// Internet Explorer
connection = new ActiveXObject("htmlfile");
connection.open();
connection.write("<html>");
connection.write("<script>document.domain = '" +
document.domain +
"'; </s" + "cript>");
connection.write("</html>");
connection.close();
iframediv = connection.createElement("div");
connection.appendChild(iframediv);
connection.parentWindow.comet = self;
iframediv.innerHTML = "<iframe src='"
+ opts.bind_url + callback
+ "'></iframe>";
// to have ability calling parent.comet.callback
}
else
{// not Internet Explorer
// create external iframe
connection = document.createElement('iframe');
connection.style.left = top = "-100px";
connection.style.height = width = "1px";
connection.style.visibility = "hidden";
connection.style.display = 'none';
iframediv = document.createElement('iframe');
iframediv.setAttribute(
'src',
opts.bind_url + callback
);
connection.appendChild(iframediv);
document.body.appendChild(connection);
}
Для IE создавать нужно иначе, чем в других браузерах. В FF работает нормально, иногда индикатор загрузки появляется при первом создании iframe, но после первого xhr запроса пропадает.
В опере такой хак у меня не работает вообще, работает только если сделать один видимый iframe (у оперы своя логика отрисовки контента, грубо примерно так: "то, что невидимо, не подлежит парсингу").
В сафари работает, в хроме не пробовал.
Лично я проанализировав разные варианты Comet пришел к выводу что long poll самый оптимальный из них.
1) отправляя XHR реквест, можно грамотно написать обработчик на все серверные ошибки
2) разрыв связи по будет всегда, только задержка разная - это например проблема прокси, которая не получив от сервера что передача окончена может просто обрубить клиента (а ведь почти на всех рабочих местах стоит прокся). А создавая XHR самостоятельно (а не средствами браузера в Iframe), можно отследить когда связь разорвется.
3) Как много бы вы не слышали от серверных программистом что Comet это технология при которой происходит с клиента всего один запрос.... Это все миф, отсюда следствие. Несмотря на небольшое увеличение входящего траффика на сервер, long poll на данный момент является самым оптимальным и удобным средством для Comet технологии.
По поводу перехвата ошибок
Я провёл небольшое исследование на эту тему
iframe я создаю динамически, при этом история браузера не засоряется.
Для детектирования установки связи, после form_.submit() нужно создать таймер, и если скажем в течении 3-х секунд(в зависимости от размера запроса) первый ответ от сервера не пришёл значит связь не установилась.
По поводу разрыва связи (в том числе и при нажатии кнопки отмена в браузере) это всё прекрасно детектируется, но у каждого браузера по разному.
//=============== Создание Iframe ==============================
//t.id индентификатор Iframe Это может быть просто число, или время в мс.
// LocUrl Это url файла фрейма, допускаются параметры my_frame.php?z=1
var div_ = document.createElement('div');
div_.innerHTML =
'<div style="">' +
'<iframe '+
'name="name_iframe_'+t.id+'" '+
'id="id_iframe_'+t.id+'" '+
'style="height:1px;width:1px;visibility:hidden;position:absolute">'+
'</iframe>'+
'<form '+
'id="id_form_'+t.id+'" '+
'action="'+LocUrl+'" '+
'method="POST" '+
'target="name_iframe_'+t.id+'" '+
'enctype="multipart/form-data">'+
'<INPUT TYPE="text" name="id_" VALUE="'+t.id+'">'+
'<INPUT TYPE="text" name="params_" VALUE="'+serialize(Params)+'">'+
'</form>'+
'</div>';
div_.setAttribute('id','id_div_'+t.id);
document.body.appendChild(div);
var form_=document.getElementById("id_form_"+t.id);
form_.submit();
//Переменные form_ и div_ хранить не нужно, все обращения лучше сделать через
// document.getElementById("id_div_"+t.id)
//=============== Удаление iframe ==============
if(div_=document.getElementById("id_div_"+t.id))
div_.parentNode.removeChild(div_); //IE 6 на это иногда неадекватно реагирует
//================ Проверка связи ==========================
//====1-я проверка ===== По таймеру скажем в 1 сек, вызываем эту проверку
try{
St=window.frames['id_iframe_'+t.id].document.readyState+' '; //FireFox не знает такого
if(St=='complete '){//В принципе это возможно только в IE 6, может и выше
// Обрыв связи. Или сервер закрыл соединение
};
} catch(e){ } ;
//============================================================
//====2-я проверка ===== Регистрируем CallBack функцию
function ServerPushInstall(Obj){
if (Obj.addEventListener) {//Этот метод есть не во всех браузерах
//Регистриум Функцию ServerPushLoad_DOM, которая будет вызвана при разрыве связи
Obj.addEventListener("DOMContentLoaded", ServerPushLoad_DOM, false);
};
};
//
===================================================================
//В HTML коде Iframe в первую очередь должно быть вызвано
parent.ServerPushInstall(document);
Здесь представлены 2 варианта проверок, потому как некоторые работаю только в определенных браузерах, всё это было проверено в IE6, FireFox 3.5, Opera 10.
Мои проверки скорее всего заставляют браузер проверять наличие TCP соединения. Но операционная система не всегда может определить разрыв TCP соединения, особенно когда по нему ничего не передаётся. Поэтому сервер, в любом случае, раз 30 сек – минуту должен посылать сообщение о том, что он жив.
Первоначально в iframe должно быть послано порядка 2-х килобайт текста(хоть пробелов)
Затем можно посылать короткие сообщения
<script>parent.MyMessage('');</script>\r\n
и все они будут сразу-же обрабатываться.
Единственное, что мне пока не нравится в этом способе ajax, так это то, что мне не удалось избавится от курсора с песочными часами. У пользователя может возникнуть неправильное представление о том, что html страница ещё не загрузилась.
Несколько слов о многопоточности в Java скрипт. Во всех браузерах кроме оперы её нет, простой цикл
while(true){};
завешивает все "вкладки" браузера. Но такой цикл в Opera практически не заметен для пользователя, скажу больше если такой цикл сделать в iframe, то скрипты в основном html продолжат работать. Поэтому из Iframe правильнее всего передавать сообщение главному html только так
>> div_.parentNode.removeChild(div_); //IE 6 на это иногда неадекватно реагирует
после такого opera выполняет javascript до первого alert(или window.scrollTo(), или document.fire...), всё что, ниже не выполняется... т.е. если после удаления фрейма писать код не используя alert то всё работает, а если он есть то только до него..
так в чем тогда выигрыш? если просто периодичность опроса с клиента перенесена на сервер.
то есть, здесь приведен пример кода бесконечного ифрейма с бесконечным циклом.
но получается, что теперь "бесконечно" идут запросы не с клиента, а на сервере.
Я имею ввиду вот что. если реализовывать чат, и сообщения складывать, например в файл. то получается серверный код бесконечного ифрейма бесконечно считывает информацию (сообщения) из файла, чтобы потом их раздать другим клиентам для отображения.
может я чего-то не понимаю, но получается, как уже написал, что "бесконечный" запрос запускаемый javascript'ом, перенесен на сервер в, например, php скрипт с бесконечный циклом....
не пойму в данном случае, к примеру код в iframe
<script src='jq/jquery.js'></script>
$(document).ready(function()
{....}
ни в какую не хотел выполнять.
Это всё из-за того что iframe кэшируется браузером?
P:S
У меня решилось так - если подгрузить скрипт в тело
<? echo"<script>".file_get_contents('jq/jqf.js')."</script>"?>
При за пуске этого этого бесконечного цикла соединение на моем сервере разрывается каждый раз ровно через 2 минуты. Сервер Zend Server CE. Сначала думал какой то лимит браузера, но этот же браузер обрабатывает бесконечный цикл ифрейма вашей страницы без проблем. Видимо дело в сервере. Искал по конфигам сервера что то типо 2 минуты или 120 секунд, ничего не нашел.
At first, I thought t some kind of browser limit, but the same browser handles the infinite iframe loop of your page without problems. Looks like it's in the server. interior home painters near me
«Бесконечный IFrame — один из краеугольных камней ранних и современных приложений AJAX». Я только сейчас узнал об этом. Я слишком устарел? С каких это пор оно появилось, woodoku?
There was an impressive presentation in this amazing web presence. We were happy to see it again, and no doubt we continue to look for something unique. 안전보증메이저사이트
I am grateful that you shared this knowledge with me. I truly enjoy the post that you made on your blog a lot. You have provided readers with a blog post that is both instructive and interesting. run 3
Этот текст относится к использованию IFrames в приложении AJAX. В нем объясняется, как IFrame используется в качестве канала связи для отправки данных с сервера на главную страницу. Однако использование IFrame имеет некоторые проблемы, включая обработку сценариев браузером, my location и отображение индикатора загрузки страницы. Вы можете поэкспериментировать с загрузкой бесконечного IFrame, чтобы проверить индикатор загрузки страницы вашего браузера.
Этот метод, хотя и является хаком, позволяет поддерживать постоянное соединение между клиентом и сервером, помогая эффективно передавать данные. Однако также важно обратить внимание на такие вопросы, как кэширование скриптов и отображение сообщений о загрузке. Решение этих проблем важно для обеспечения бесперебойной работы пользователя. iq test free online
Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены. Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
А можно ли в ифрейме масштабировать вставляемый сайт?
Конечно можно
Всегда использовал и буду использовать мои любимые водные фреймы!!!
реально удобно делать приложения уровня AJAX.
Илья, для того, чтобы не было эффектов в статусбаре, можно iframe-загрузчик поместить в другой iframe-обертку, у которого src пустой, а для IE нужно указать в iframe-обертке
Что вы имели ввиду?
Попробовал ваш совет, и как-то не ощутил эффекта:
Вот код создания iframe - по сути, код некоторой функции connect:
Для IE создавать нужно иначе, чем в других браузерах. В FF работает нормально, иногда индикатор загрузки появляется при первом создании iframe, но после первого xhr запроса пропадает.
В опере такой хак у меня не работает вообще, работает только если сделать один видимый iframe (у оперы своя логика отрисовки контента, грубо примерно так: "то, что невидимо, не подлежит парсингу").
В сафари работает, в хроме не пробовал.
Интересно, как можно поймать ошибку отсутствия соединения.
Есть какие-нибудь идеи?
Обычно такие ошибки ловятся установкой
<body onload="...">
.При любом разрыве соединения вызывается этот обработчик.
Этот обработчик срабатывает не всегда, и только если сервер разорвал соединение.
Я пока не придумал ничего лучше периодического push'а от сервера (если push не пришел всрок, то клиент переустанавливает соединение).
Лично я проанализировав разные варианты Comet пришел к выводу что long poll самый оптимальный из них.
1) отправляя XHR реквест, можно грамотно написать обработчик на все серверные ошибки
2) разрыв связи по будет всегда, только задержка разная - это например проблема прокси, которая не получив от сервера что передача окончена может просто обрубить клиента (а ведь почти на всех рабочих местах стоит прокся). А создавая XHR самостоятельно (а не средствами браузера в Iframe), можно отследить когда связь разорвется.
3) Как много бы вы не слышали от серверных программистом что Comet это технология при которой происходит с клиента всего один запрос.... Это все миф, отсюда следствие. Несмотря на небольшое увеличение входящего траффика на сервер, long poll на данный момент является самым оптимальным и удобным средством для Comet технологии.
Long polling годиться если частота поступающих данных невелика.
Если будет приходить по 10-100 событий в секунду, то спасет только бесконечный ифрейм.
По поводу перехвата ошибок
Я провёл небольшое исследование на эту тему
iframe я создаю динамически, при этом история браузера не засоряется.
Для детектирования установки связи, после form_.submit() нужно создать таймер, и если скажем в течении 3-х секунд(в зависимости от размера запроса) первый ответ от сервера не пришёл значит связь не установилась.
По поводу разрыва связи (в том числе и при нажатии кнопки отмена в браузере) это всё прекрасно детектируется, но у каждого браузера по разному.
===================================================================
//В HTML коде Iframe в первую очередь должно быть вызвано
Здесь представлены 2 варианта проверок, потому как некоторые работаю только в определенных браузерах, всё это было проверено в IE6, FireFox 3.5, Opera 10.
Мои проверки скорее всего заставляют браузер проверять наличие TCP соединения. Но операционная система не всегда может определить разрыв TCP соединения, особенно когда по нему ничего не передаётся. Поэтому сервер, в любом случае, раз 30 сек – минуту должен посылать сообщение о том, что он жив.
Первоначально в iframe должно быть послано порядка 2-х килобайт текста(хоть пробелов)
Затем можно посылать короткие сообщения
и все они будут сразу-же обрабатываться.
Единственное, что мне пока не нравится в этом способе ajax, так это то, что мне не удалось избавится от курсора с песочными часами. У пользователя может возникнуть неправильное представление о том, что html страница ещё не загрузилась.
Несколько слов о многопоточности в Java скрипт. Во всех браузерах кроме оперы её нет, простой цикл
завешивает все "вкладки" браузера. Но такой цикл в Opera практически не заметен для пользователя, скажу больше если такой цикл сделать в iframe, то скрипты в основном html продолжат работать. Поэтому из Iframe правильнее всего передавать сообщение главному html только так
>> div_.parentNode.removeChild(div_); //IE 6 на это иногда неадекватно реагирует
после такого opera выполняет javascript до первого alert(или window.scrollTo(), или document.fire...), всё что, ниже не выполняется... т.е. если после удаления фрейма писать код не используя alert то всё работает, а если он есть то только до него..
это бага или фича в opera'е?
так в чем тогда выигрыш? если просто периодичность опроса с клиента перенесена на сервер.
то есть, здесь приведен пример кода бесконечного ифрейма с бесконечным циклом.
но получается, что теперь "бесконечно" идут запросы не с клиента, а на сервере.
Я имею ввиду вот что. если реализовывать чат, и сообщения складывать, например в файл. то получается серверный код бесконечного ифрейма бесконечно считывает информацию (сообщения) из файла, чтобы потом их раздать другим клиентам для отображения.
может я чего-то не понимаю, но получается, как уже написал, что "бесконечный" запрос запускаемый javascript'ом, перенесен на сервер в, например, php скрипт с бесконечный циклом....
В примере статьи опечатка
При эхе блока скрипта нужно $i выделить точками, чтоб вставлялось значение.
Это часто так бывает когда пишешь как пхп строит код явыскрипт и в голове они путаются, и что это <?php alert('Hello') ?> не работает
Здесь нет опечатки. Переменные внутри двойных кавычек интерполируются.
не пойму в данном случае, к примеру код в iframe
<script src='jq/jquery.js'></script>
$(document).ready(function()
{....}
ни в какую не хотел выполнять.
Это всё из-за того что iframe кэшируется браузером?
P:S
У меня решилось так - если подгрузить скрипт в тело
<? echo"<script>".file_get_contents('jq/jqf.js')."</script>"?>
А если писать script без body и head, насколько это будет некроссбраузерным?
Добрый день, такая проблема:
При за пуске этого этого бесконечного цикла соединение на моем сервере разрывается каждый раз ровно через 2 минуты. Сервер Zend Server CE. Сначала думал какой то лимит браузера, но этот же браузер обрабатывает бесконечный цикл ифрейма вашей страницы без проблем. Видимо дело в сервере. Искал по конфигам сервера что то типо 2 минуты или 120 секунд, ничего не нашел.
Подскажите, пожалуйста, в чем может быть дело?
Скажите а исправить статус загрузки нельзя? Например часики в опере и анимация в хроме?
Новости
At first, I thought t some kind of browser limit, but the same browser handles the infinite iframe loop of your page without problems. Looks like it's in the server. interior home painters near me
«Бесконечный IFrame — один из краеугольных камней ранних и современных приложений AJAX». Я только сейчас узнал об этом. Я слишком устарел? С каких это пор оно появилось, woodoku?
connect 4 An effective way of entertainment
There was an impressive presentation in this amazing web presence. We were happy to see it again, and no doubt we continue to look for something unique. 안전보증메이저사이트
I am grateful that you shared this knowledge with me. I truly enjoy the post that you made on your blog a lot. You have provided readers with a blog post that is both instructive and interesting. run 3
Этот текст относится к использованию IFrames в приложении AJAX. В нем объясняется, как IFrame используется в качестве канала связи для отправки данных с сервера на главную страницу. Однако использование IFrame имеет некоторые проблемы, включая обработку сценариев браузером, my location и отображение индикатора загрузки страницы. Вы можете поэкспериментировать с загрузкой бесконечного IFrame, чтобы проверить индикатор загрузки страницы вашего браузера.
Play word games for free at waffle game. You will have comfortable moments with friends and family. Moments of relief after tiring work waffle
Этот метод, хотя и является хаком, позволяет поддерживать постоянное соединение между клиентом и сервером, помогая эффективно передавать данные. Однако также важно обратить внимание на такие вопросы, как кэширование скриптов и отображение сообщений о загрузке. Решение этих проблем важно для обеспечения бесперебойной работы пользователя. iq test free online
Отправить комментарий
Приветствуются комментарии:Для остальных вопросов и обсуждений есть форум.