JavaScript. Подробное руководство, 6-е издание, стр. 288

<b>        // Отобразить сведения во всплывающей подсказке,</b>

<b>        link.title = &quot;Тип: &quot; + type + &quot; \n&quot; +</b>

<b>                     &quot;Размер: &quot; + size + &quot; \n&quot; + &quot;Дата: &quot; + date;</b>

<b>      }</b>

<b>      else {</b>

<b>        // Если запрос не удался и подсказка для ссылки еще не содержит текст</b>

<b>        // &quot;Ссылка на другой сайт&quot;, вывести сообщение об ошибке,</b>

<b>        if (!link.title)</b>

<b>          link.title = &quot;Невозможно получить сведения: \n&quot; + req.status + &quot; &quot; + req.statusText;</b>

<b>      }</b>

<b>    };</b>

<b>    req.send(null);</b>

<b>    // Удалить обработчик: попытка получить сведения выполняется только один раз.</b>

<b>    if (link.removeEventListener)</b>

<b>      link.removeEventListener(&quot;mouseover&quot;, mouseoverHandler, false);</b>

<b>    else</b>

<b>      link.detachEvent(&quot;onmouseover&quot;, mouseoverHandler);</b>

<b>  }</b>

<b>});</b>

18.2. Выполнение НТТР-запросов с помощью <script>: JSONP

В начале этой главы упоминалось, что элемент

<b>&lt;script&gt;</b>
можно использовать в качестве Ajax-транспорта: достаточно установить атрибут
<b>src</b>
элемента
<b>&lt;script&gt;</b>
(и вставить его в документ, если он еще не внутри документа), и броузер сгенерирует HTTP-запрос, чтобы загрузить содержимое ресурса по указанному URL-адресу. Основная причина, почему элементы
<b>&lt;script&gt;</b>
являются удобным Ajax-транспортом, состоит в том, что они не являются субъектами политики общего происхождения и их можно использовать для запроса данных с других серверов. Вторая причина состоит в том, что элементы
<b>&lt;script&gt;</b>
автоматически декодируют (т. е. выполняют) тело ответа, содержащего данные в формате JSON.

Прием использования элемента

<b>&lt;script&gt;</b>
в качестве Ajax-транспорта известен под названием JSONP: это способ организации взаимодействий, когда в теле ответа на HTTP-запрос возвращаются данные в формате JSON. Символ «Р» в аббревиатуре означает «padding», или «prefix» (дополнение или приставка), но об этом чуть ниже. [51]

Представьте, что вы пишете службу, которая обрабатывает GET-запросы и возвращает данные в формате JSON. Документы с общим происхождением могут пользоваться этой службой с помощью объекта

<b>XMLHttpRequest</b>
и метода
<b>JSON.parse()</b>
, как показано в примере 18.3. Если на сервере будет настроена отправка заголовка «CORS», сторонние документы при отображении в новых броузерах также смогут пользоваться службой с помощью объекта
<b>XMLHttpRequest</b>
. Однако при отображении в старых броузерах, не поддерживающих заголовок «CORS», сторонние документы смогут получить доступ к службе только с помощью элемента
<b>&lt;script&gt;.</b>
Ответ в формате JSON является (по определению) допустимым программным кодом на языке JavaScript, и броузер выполнит его при получении. При выполнении данных в формате JSON происходит их декодирование, но полученный результат является обычными данными, которые ничего не делают.

Именно здесь на сцену выходит символ «Р» из аббревиатуры JSONP. Когда обращение к службе реализовано с помощью элемента

<b>&lt;script&gt;,</b>
служба должна «дополнить» ответ, окружив его круглыми скобками и добавив в начало имя JavaScript-функции. То есть вместо того чтобы отправлять данные, такие как:

<b>[1, 2, {&quot;buckle&quot;: &quot;my shoe”}]</b>

она должна отправлять дополненные данные, как показано ниже:

<b>handleResponse(</b>

<b>       [1. 2. {&quot;buckle&quot;: &quot;my shoe&quot;}]</b>

<b>)</b>

Являясь телом элемента

<b>&lt;script&gt;,</b>
этот дополненный ответ уже будет выполнять некоторые действия: он произведет преобразование данных из формата JSON (которые в конечном итоге являются одним длинным выражением на языке JavaScript) и передаст их функции
<b>handleResponse(),</b>
которая, как предполагается, определена в теле документа и выполняет некоторые операции с данными.

Сценарии и безопасность

Используя элемент <script> в качестве Ajax-транспорта, вы разрешаете своей веб-странице выполнять любой программный код на языке JavaScript, который отправит удаленный сервер. Это означает, что прием, описываемый здесь, не должен использоваться при работе с серверами, не вызывающими доверия. Впрочем, даже при работе с доверенным сервером следует помнить, что этот сервер может быть взломан злоумышленником, и злоумышленник сможет заставить вашу веб-страницу выполнить любой программный код и отобразить любую информацию, какую он пожелает, и эта информация будет выглядеть, как если бы она поступила с вашего сайта.

При этом следует отметить, что для веб-сайтов стало обычным делом использовать доверенные сценарии сторонних разработчиков, особенно сценарии, используемые для внедрения в страницу рекламы или «виджетов». Использование элемента <script> в качестве Ajax-транспорта для взаимодействия с доверенными веб-службами ничуть не опаснее.

*************************************

Чтобы этот прием действовал, необходимо иметь некоторый способ сообщить службе, что обращение к ней выполняется с помощью элемента

<b>&lt;script&gt;</b>
и она должна возвращать ответ не в формате JSON, а в формате JSONP. Это можно сделать, указав параметр запроса в адресе URL, например, добавив в конец
<b>?jsonp</b>
(или
<b>&amp;jsonp</b>
).