На этом шаге мы рассмотрим некоторые ограничения безопасности и способы их обхода.
При всей своей значимости для разработки динамических веб-приложений объект XMLHttpRequest (технология, лежащая в основе реализации поддержки AJAX в библиотеке jQuery) подчиняется строгим ограничениям. Чтобы предотвратить возможность атак типа межсайтовый скриптинг, этот объект не дает возможность запрашивать документы с сервера, отличного от того, где была получена оригинальная страница.
В большинстве случаев это правильно. Например, некоторые считают реализацию интерпретации данных в формате JSON с помощью функции eval() небезопасной. Если в файле с данными будет присутствовать злонамеренный программный код, он будет выполнен при вызове функции eval(). Однако так как файл с данными должен находиться на том же сервере, что и веб-страница, вероятность внедрения программного кода в файл данных практически равна вероятности внедрения этого кода в саму страницу. Это означает, что при загрузке файлов в формате JSON из доверенных источников использование функции eval() не представляет серьезной угрозы безопасности.
Тем не менее, часто бывает целесообразно загружать данные из сторонних источников. Чтобы обеспечить такую возможность и обойти ограничения безопасности, имеется несколько способов.
Один из методов заключается в том, чтобы сервер сам загружал данные из удаленного источника и передавал их клиенту по запросу. Это очень мощный прием, так как в случае необходимости на сервере можно организовать предварительную обработку данных. Например, мы могли бы загружать из разных источников файлы XML, содержащие ленты новостей RSS, собирать их в единую ленту на сервере и предоставлять этот новый файл клиенту по запросу.
Чтобы загрузить данные из удаленного источника без привлечения сервера, нам придется действовать исподтишка. Распространенный способ загрузки посторонних файлов JavaScript заключается во внедрении тегов <script> по мере необходимости. Это легко реализовать благодаря возможности с помощью библиотеки jQuery вставлять новые элементы в дерево DOM:
$(document.сreateElement('script')) .attr('src', 'http://example.ru/example.js') .appendTo('head');
Фактически метод $.getScript() будет автоматически использовать описанную методику при обнаружении имени удаленного сервера в своем аргументе с адресом URL, поэтому все, что необходимо, делается без нашего участия.
Браузер выполнит загруженный сценарий, но он не имеет механизма, который позволил бы получить результаты работы этого сценария. По этой причине, чтобы использовать данный прием, необходимо содействие удаленного сервера. Загруженный сценарий должен предпринять некоторое действие, например определить значение глобальной переменной, чтобы оказать воздействие на окружение. Службы, предоставляющие сценарии, которые запускаются таким способом, кроме того предоставляют описание прикладного интерфейса (API), посредством которого обеспечивается взаимодействие с удаленным сценарием.
Другая возможность состоит в применении тега <iframe> для загрузки удаленных данных. Этот элемент позволяет указывать в качестве источника данных любой адрес URL, даже если он не совпадает с адресом сервера, откуда была получена оригинальная страница. С помощью этого тега легко можно загружать и отображать данные на странице. Однако для обеспечения возможности манипулирования этими данными, как правило, требуется такое же содействие удаленного сервера, как и в случае с использованием тега <script>, - сценарии внутри тега <iframe> должны явно передавать данные в объекты родительского документа.
На следующем шаге мы рассмотрим использование формата JSONP для удаленных данных.