Еще одной проблемой, решаемой в традиционном вебе с помощью нагромождения различных изящных трюков, в народе поэтично прозванных костылями, является обмен сообщениями между страницами, фреймами, окнами или вкладками браузера, да и вообще взаимодействие скрипта на веб-странице с неким произвольным источником. На произвольном домене. Почему тут возникают сложности? Все дело в ограничениях, которые производители браузеров накладывают по соображениям небезопасности. Действительно, при свободном обмене сообщениями клиент не застрахован от чтения содержимого своего браузера злоумышленницами, ну а об опасности выполнения javaScript, пришедшего с непроверенного сервера, можно и не говорить. К слову, новичкам стоит взять на заметку, что обнаружение новых уязвимостей — это постоянный процесс, и потому нужно регулярно уделять определенное количество времени изучению новых технологий и их слабых мест techcraunch, дабы оставаться в тренде, и иметь возможность своевременно решить проблемы связанные с безопасностью.
Но, несмотря на все опасности, потребность в такого рода общении в современных веб-приложениях довольно высока, и техническое решение, безопасно осуществляющее такое взаимодействие, давно было востребовано. В конце концов, производители браузеров и смотрители стандартов выработали новую спецификацию — Cross Document Messages, в рамках которой выработан Web Messaging API — средство общения между документами, свободное от междо-менных ограничений. Пользоваться им очень просто, и начнем мы прямо сейчас:
<script>
Window. SostMessage(«Hello», «http://remotehost. com»}) </script>
Мы послали сообщение «Hello» скрипту, находящемуся в домене remotehost. com.
Для принятия сообщений следует привязать к событию message функцию обратного вызова:
Window. addEventListener(«message», messageHadler, false);
Она получает в качестве аргумента объект события, из которого можно извлечь не только данные, но и их источник, обеспечив таким образом безопасность:
Function messageHadler(e){
If(e. origin == «http://htmotehost»){ alert(e. origin+» «+e. data);
}
}
Разберем небольшой пример. Пусть у нас будет следующая HTML-разметка:
<html>
<meta charset=»cp1251″ />
<body>
<iframe src=»Http://localhost/cdm/frame. html» id=»target_frame»></iframe> form id=»form1″>
<input type=»text» id=»msg» placeholder=»Введите ваше сообщение»/> <input type=»submit»/>
</form>
<script>
Var target_win = document. getElementById(«target_frame»).contentWindow;
Document. getElementById(«form1»). onsubmit = function(){ target_win. fostMessage(
Document. get ElementById(«msg»).value,
);
Return false:
}
</script>
</body>
</html>
Тут, как следует из адреса, и фрейм, и исходная страница расположены на одном домене, а именно на Http://localhost, то есть прямо на машине, где пишутся эти строки. Это сделано для того, чтобы вам было легче воспроизвести все эксперименты. Разумеется, в реальности адреса и домены будут разные.
Теперь код фрейма frame. html: |
|
<html> | |
<body> | |
<meta charset=»cp1251″ /> | |
<div id=»test»>Сообщения:</div> | |
<script> | |
Window. addEventListener(«message», postListener, false); | |
Function postListener(e){ | |
If (event. origin!== «http://localhost»){ | |
Alert(«AAAAAAAAAAAAA! Galaxy in danger!»); | |
Return: | |
Var content = document. getElementById(«test»); | |
Content. innerHTML = content. innerHTML+»<br />»+event. origin + «: » + event | . data: |
}
</script> |
|
</body> | |
</html> |
Код в фрейме выполняет проверку источника пришедшего сообщения на соответствие доверенному домену и в случае успешной проверки вставляет текст сообщения в тело страницы. Работу всего этого можно увидеть на рис. 87.
Рис. 87. «Общение» с фреймом посредством postMessages
Вопрос, заданный на перлюстрации, вполне закономерен — общение с фреймом идет в одном направлении. Исправим это обстоятельство, ведь окно — источник сообщений — доступно во фрейме через объект event. Дополним код фрейма:
Content. innerHTML = content. innerHTML+»<br />»+event. origin + «: » + event. data; var win = e. source: win. postMessage(
«Сообщение получено тчк целую тчк ваш фрейм»,
);
Теперь организуем прием сообщений на странице-источнике:
Window. addEventListener(«message», postListener, false); function postListener(e){ alert(e. data);
Рис. 88. Фрейм отвечает
Впрочем, это не единственное предназначение Web Messaging. Этот интерфейс является средством реализации спецификаций WebWorkers и WebSockets (обо всем этом разговор еще впереди) и уже рассмотренного нами Server-Sent Events. В общем, он вполне претендует на роль универсального программного интерфейса для объектов HTML5.
Проверяем — рис. 88. Все работает, мы научились общаться с фреймами.
?
Добавить комментарий