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

На практике веб-службы, поддерживающие JSONP, не диктуют имя функции, такое как «handleResponse», которую должны реализовать все клиенты. Вместо этого они используют значение параметра запроса, позволяя клиентам самим указывать имя функции, и применяют его для дополнения ответа. В примере 18.14 для определения имени функции обратного вызова используется параметр «jsonp». Многие службы, поддерживающие JSONP, распознают параметр с эти именем. Также достаточно часто используется параметр с именем «callback», и вы можете изменить программный код примера, чтобы он смог работать со службами, предъявляющими определенные требования.

Пример 18.14 определяет функцию get JS0NP(), которая выполняет запрос на получение данных в формате JSONP. В этом примере есть несколько тонкостей, о которых следует сказать особо. Во-первых, обратите внимание, что пример создает новый элемент

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

Пример 18.14. Выполнение запросов на получение данных в формате JSONP с помощью элемента

<b>&lt;script&gt;</b>

<b>// Выполняет запрос по указанному URL-адресу на получение данных в формате JSONP и передает </b>

<b>// полученные данные указанной функции обратного вызова. Добавляет в URL параметр запроса </b>

<b>// с именем ''jsonp'', чтобы указать имя функции обратного вызова, </b>

<b>function getJS0NP(иrl, callback) {</b>

<b>  // Создать для данного запроса функцию с уникальным именем</b>

<b>  var cbnum = &quot;cb&quot; + getJSONP.counter++; // Каждый раз увеличивать счетчик</b>

<b>  var cbname = &quot;getJSONP.” + cbnum; // Как свойство этой функции</b>

<b>  // Добавить имя функции в строку запроса url, используя формат представления данных </b>

<b>  // HTML-форм. Здесь используется параметр с именем &quot;jsonp&quot;. Некоторые веб-службы </b>

<b>  // с поддержкой JSONP могут использовать параметр с другим именем, таким как &quot;callback&quot;,</b>

<b>  if (url.indexOfC?&quot;) === -1)  // URL еще не имеет строки запроса</b>

<b>    url += &quot;?jsonp=&quot; + cbname; // добавить параметр как строку запроса</b>

<b>  else                         // В противном случае</b>

<b>    url += &quot;&amp;jsonp=&quot; + cbname; // добавить как новый параметр.</b>

<b>  // Создать элемент script, который отправит запрос</b>

<b>  var script = document.createElement(&quot;script&quot;);</b>

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

<b>  getJSONP[cbnum] = function(response) {</b>

<b>    try {</b>

<b>      callback(response); // Обработать данные</b>

<b>    }</b>

<b>    finally { // Даже если функция или ответ возбудит исключение</b>

<b>      delete getJSONP[cbnum];                // Удалить эту функцию</b>

<b>      script.parentNode.removeChild(script); // Удалить элемент script</b>

<b>    }</b>

<b>  };</b>

<b>  // Инициировать HTTP-запрос</b>

<b>  script.src = url; // Указать url-адрес элемента</b>

<b>  document.body.appendChild(script); // Добавить в документ</b>

<b>}</b>

<b>getJSONP.counter = 0; // Счетчик, используемый для создания уникальных имен</b>

18.3. Архитектура Comet на основе стандарта «Server-Sent Events»

Проект стандарта «Server-Sent Events» определяет объект

<b>EventSource</b>
, который делает практически тривиальным создание приложений с архитектурой Comet. При его использовании достаточно передать URL-адрес конструктору
<b>EventSource()</b>
и затем обрабатывать события «message» в полученном объекте:

<b>var ticker = new EventSourcefstockprices. php”);</b>

<b>ticker.onmessage = function(e) {</b>

<b>  var type = e.type;</b>

<b>  var data = e.data;</b>

<b>// Обработать строки type и data.</b>

<b>}</b>

Объект события «message» имеет свойство

<b>data</b>
, хранящее строку, отправленную сервером с этим событием в качестве полезной нагрузки. Кроме того, объект события имеет свойство
<b>type</b>
, как и все другие объекты событий. По умолчанию это свойство имеет значение «message», но источник события может указать в этом свойстве другую строку. Все события от данного сервера, источника событий, обрабатываются единственным обработчиком
<b>onmessage</b>
, который при необходимости может передавать их другим обработчикам, опираясь на свойство
<b>type</b>
объекта события.

Протокол обмена, определяемый стандартом «Server-Sent Event», достаточно прост. Клиент устанавливает соединение с сервером (когда создает объект

<b>EventSource</b>
), а сервер сохраняет это соединение открытым. Когда происходит событие, сервер передает через соединение текстовую строку. Передача события через сеть выглядит примерно следующим образом: