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. то іфрейм після створення робиться невидимим.
Динамічне створення іфрейма переслідує дві мети:
- Робимо HTML чистіше
- Динамічний іфрейм - ще одна міра проти забруднення history
Ви можете самостійно протестувати вплив динамічної генерації на звук кліка в IE і кнопки back-forward.
Наступний приклад працює тільки в IE. Він створює невидимий iframe, при запиті через який немає ні кліка ні зайвої хісторі, ні індикатора завантаження.
Якщо Ви перебуваєте в IE, то можете помітити, що переходи з цього іфрейму абсолютно непомітні для користувача. Ідеал, та й годі. Він створюється за допомогою
слабо документованої, але безпечної можливості ActiveX. Ніяких спеціальних опцій браузера для неї включати не треба.
Як видно з прикладу, для ізоляції іфрейма створюється проміжний документ ActiveX. Тому операції над іфреймом і не видно з основного окна.Здесь виходить, що об'єктів window не два, як зазвичай (основне вікно + іфрейм), а три:
- Основне вікно window
- Вікно документа htmlfile - доступно як IEFrameDocument.parentWindow
- Вікно іфрейма - доступно як 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" і
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 (або іншим чином (яким?). Є робочий приклад?