Ajax-транспорт iframe

Цей транспорт - мабуть, самий універсальний і потужний, але і тонкощів в ньому - більше всіх

Для спілкування з сервером створюється невидимий IFrame. Проста зміна URL цього iframe - запит до сервера за даними. Крім того, в iframe можна відправляти post-запити
поставивши його ім'я в атрибут form.target.

Як правило, iframe - один, і запити в нього по черзі відправляються. Можна зробити і більше іфреймов, щоб відправляти кілька запитів одночасно.
Однак, якщо їх більше двох - доведеться виносити на різні піддомени. Про це - в секції Обмін даними для документів з різних доменів.

  • Можлива відправка файлів користувача з диска: POST форми в iframe.
  • Звук "кліка" при переході запиті в iframe
  • Зміни в history браузера, що впливають на історію відвіданих сторінок і / або кнопки back-forward. Переходи по службовим URL не повинні позначатися на history.
  • Смуга завантаження або курсор-годинки при запиті в iframe. Запити повинні бути по можливості прозорі, невидимі для відвідувача.

А тепер - до реалізації та її особливостям, включаючи подолання описаних проблем!

Що таке iframe? На це питання у браузера дві відповіді

Коли ми говоримо про переведення iframe на новий URL - маємо на увазі "вікно". Коли збираємося створювати його і запихати в DOM - звичайно, "тег".

З сторінки всередині вікна iframe можна пройти до батьківського вікна через window.parent, і, якщо дозволяє same origin policy, навіть викликати функцію / отримати тег iframe.

Для поста - досить задати формі form атрибут form.target = 'ім'я іфрейма' і викликати form.submit (). Таким способом можна відправляти на сервер файли, і взагалі,
все що може містити форма HTML.

Сервер отримує запит, і генерує у відповідь сторінку, яка, як правило, передає результат в основне вікно через спеціальну функцію-каллбек.
У прикладах така функція з'явиться трохи пізніше, при розгляді невидимих ​​іфреймов.


Для браузера iframe - таке ж вікно, як і основне. Відповідно, переходи в ньому на різні URL повинні потрапляти в історію, браузіть туди-сюди можна через back / forward.
Наприклад, ось:

Ви можете скопіювати посилання на цей приклад і позаходіть на неї в різних браузерах. Кліки на кнопки туди-сюди ніяк не відбиваються на історії, хоча
змінюють сторінку всередині фрейму. Поки що залишається звук кліка в IE. Запити до сервера повинні бути, з одного боку, непомітні, так що доведеться від нього позбавлятися.

Результати тестів залежать від браузера, ОС і т.п. Зазвичай вийти так, що при POST history забруднюється, а при GET - немає.

Створити іфрейм - так само просто, як і будь-який інший елемент. Мабуть, єдина підстава - в IE властивість name має обов'язково задаватися при створенні елемента.
Тобто, не можна спочатку зробити iframe. а потім привласнити йому name (те ж саме і для input, і т.п.) - будуть проблеми. Тому доводиться робити окрему перевірку на isIE.

Якщо не заданий параметр debug. то іфрейм після створення робиться невидимим.

Динамічне створення іфрейма переслідує дві мети:

  1. Робимо HTML чистіше
  2. Динамічний іфрейм - ще одна міра проти забруднення history

Ви можете самостійно протестувати вплив динамічної генерації на звук кліка в IE і кнопки back-forward.

Наступний приклад працює тільки в IE. Він створює невидимий iframe, при запиті через який немає ні кліка ні зайвої хісторі, ні індикатора завантаження.

Якщо Ви перебуваєте в IE, то можете помітити, що переходи з цього іфрейму абсолютно непомітні для користувача. Ідеал, та й годі. Він створюється за допомогою
слабо документованої, але безпечної можливості ActiveX. Ніяких спеціальних опцій браузера для неї включати не треба.

Як видно з прикладу, для ізоляції іфрейма створюється проміжний документ ActiveX. Тому операції над іфреймом і не видно з основного окна.Здесь виходить, що об'єктів window не два, як зазвичай (основне вікно + іфрейм), а три:

  1. Основне вікно window
  2. Вікно документа htmlfile - доступно як IEFrameDocument.parentWindow
  3. Вікно іфрейма - доступно як IEFrameNode.contentWindow. або з використанням getIframeDocument

Глобальні змінні IEFrameNode. IEFrameDocument дають нам прямий доступ з основного вікна у вікна 2 і 3. Так що можна легко відправити запит на сервер викликом

Але що далі? Документ з сервера, напевно, захоче звернутися до основного вікна. Наприклад, викликати його функцію handleMessage () з деяким повідомленням.

Щоб такий доступ отримати, потрібно заздалегідь, з основного вікна, протягнути посилання з вікна htmlfile в основне вікно:

Обмін даними проілюстрований на малюнку:

Якщо Ви вирішите використовувати цей підхід - дозвольте мені заощадити можливі годинник копання в отладчике. До цього обговорювалося метод GET.
У ньому досить посилання на iframe.

З іншого боку, в методі POST потрібно присвоїти form.target не саме іферейм, а ім'я іфрейма, причому цей іфрейм має бути видно з поточного вікна.

Легко перевірити, що простий пост в фрейм "frame3" (в прикладі) не дасть результату, т.к цей фрейм непомітний.

Для того, щоб форма побачила іфрейм, її потрібно створити в тому ж вікні. Це можна зробити масою способів. Наприклад, додати потрібні скрипти в htmlfile:

І викликати надсилання форми з потрібного вікна:

Все основне, сподіваюся, в тексті є. Якщо є більш глибокий інтерес - приємного копання в отладчике.

Описаний спосіб пропонує ідеальну реалізацію iframe-транспорту, яка, на жаль, працює тільки в IE. А для інших браузерів можна використовувати або звичайний iframe-транспорт, або інші транспорти.

Базовий приклад використання iframe для COMET c використанням GET ви можете завантажити.

  • Версія для друку

Ось така проблема. Ніде не можу знайти відповідь. Якщо в айфрейм використовуєш посилання на чужий сайт. То в айфрейм сторінка завантажується з лівого верхнього кута. А іноді необхідно щоб вікно довантажувати з середини або після відступу 100 пікселів зверху, Або що саме правельно вставити в Айфрі пошук який за зразком знайде потрібну ділянку на сторінці і довантажити починаючи з нього. Завдання мені здалася спочатку елементарної вствіть б скрипт пошуку всередину вікна і вбити замість змінної постійну, однак чомусь не вийшло нічого.

У цьому ключі зробив прогу, але. працює наполовину. Хто подскажет- чому і як краще зробити?

робиться:
1) Перший script через document.getElementById ( 'a1'). InnerHTML забирає "різне" і малює форми


і другу
де "разное-2" = F ( "різне" + KB) - все робиться ОК

2) Другий script через document.getElementById ( 'textar'). InnerHTML забирає "разное-2" і - все робиться ОК -> на php потрапляє "разное-2", і через секунду fout1 заповнюється відповіддю "bla-bla-bla"

3) Третій script пробує:
var str1 = document.getElementById ( 'a3'). innerHTML
var str1 = document.getElementById ( 'a3'). value (дурість, але пробує)
var str1 = document.getElementById ( 'fout1'). innerHTML
та ін.
- намагається виколупати з з fout1 "bla-bla-bla" через 10 секунд після post. але нічого не виходить. У чому помилка?

Як ще можна реалізувати функцію var str1 =. (Відповідь від php на post-запит), або вибити з php в java-функцію результат на запит "разное-2" по протоколу post (або іншим чином (яким?). Є робочий приклад?

Схожі статті