Javascript json ответ сервера

Протокол JSONP

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Если создать тег , то при добавлении в документ запустится процесс загрузки src . В ответ сервер может прислать скрипт, содержащий нужные данные.

Таким образом можно запрашивать данные с любого сервера, в любом браузере, без каких-либо разрешений и дополнительных проверок.

Протокол JSONP – это «надстройка» над таким способом коммуникации. Здесь мы рассмотрим его использование в деталях.

Запрос

Простейший пример запроса:

function addScript(src) < var elem = document.createElement("script"); elem.src = src; document.head.appendChild(elem); >addScript('user?id=123');

Такой вызов добавит в документа тег:

При добавлении тега с внешним src в документ браузер тут же начинает его скачивать, а затем – выполняет.

В данном случае браузер запросит скрипт с URL /user?id=123 и выполнит.

Обработка ответа, JSONP

В примере выше рассмотрено создание запроса, но как получить ответ? Допустим, сервер хочет прислать объект с данными.

Конечно, он может присвоить её в переменную, например так:

…А браузер по script.onload отловит окончание загрузки и прочитает значение user .

Но что, если одновременно делается несколько запросов? Получается, нужно присваивать в разные переменные.

Протокол JSONP как раз и призван облегчить эту задачу.

    Вместе с запросом клиент в специальном, заранее оговорённом, параметре передаёт название функции. Обычно такой параметр называется callback . Например :

Это и называется JSONP («JSON with Padding»).

Клиентский код должен доверять серверу при таком запросе. Ведь серверу ничего не стоит добавить в скрипт любые команды.

Реестр CallbackRegistry

В примере выше функция onUserData должна быть глобальной, ведь выполняется в глобальной области видимости.

Хотелось бы не загрязнять глобальное пространство имён, или по крайней мере свести загрязнение к минимуму.

Как правило, для этого создают один глобальный объект «реестр», который мы назовём CallbackRegistry . Далее для каждого запроса в нём генерируется временная функция.

Сервер обернёт ответ в функцию CallbackRegistry.func12345 , она вызывает нужный обработчик и очищает память, удаляя себя.

Читайте также:  Php массив убрать дубликаты

Далее мы посмотрим более полный код всего этого, но перед этим – важный момент! Нужно предусмотреть обработку ошибок.

Обнаружение ошибок

При запросе данных при помощи SCRIPT возможны различные ошибки:

  1. Скрипт может не загрузиться: отказ в соединении, разрыв связи…
  2. Ошибка HTTP, например 500.
  3. Скрипт загрузился, но внутри некорректен и не вызывает функцию. Например, на сервере произошла ошибка и в ответе передан её текст, а вовсе не данные.

Чтобы отловить их все «одним махом», используем следующий алгоритм:

  1. Создаётся .
  2. На ставятся обработчики onreadystatechange (для старых IE) и onload/onerror (для остальных браузеров).
  3. При загрузке скрипт выполняет функцию-колбэк CallbackRegistry. . Пусть она при запуске ставит флажок «все ок». А мы в обработчиках проверим – если флага нет, то функция не вызывалась – стало быть, ошибка при загрузке или содержимое скрипта некорректно.

Полный пример

Итак, код функции, которая вызывается с url и колбэками.

Он совсем небольшой, а без комментариев был бы ещё меньше:

var CallbackRegistry = <>; // реестр // при успехе вызовет onSuccess, при ошибке onError function scriptRequest(url, onSuccess, onError) < var scriptOk = false; // флаг, что вызов прошел успешно // сгенерировать имя JSONP-функции для запроса var callbackName = 'cb' + String(Math.random()).slice(-6); // укажем это имя в URL запроса url += ~url.indexOf('?') ? '&' : '?'; url += 'callback=CallbackRegistry.' + callbackName; // ..и создадим саму функцию в реестре CallbackRegistry[callbackName] = function(data) < scriptOk = true; // обработчик вызвался, указать что всё ок delete CallbackRegistry[callbackName]; // можно очистить реестр onSuccess(data); // и вызвать onSuccess >; // эта функция сработает при любом результате запроса // важно: при успешном результате - всегда после JSONP-обработчика function checkCallback() < if (scriptOk) return; // сработал обработчик? delete CallbackRegistry[callbackName]; onError(url); // нет - вызвать onError >var script = document.createElement('script'); // в старых IE поддерживается только событие, а не onload/onerror // в теории 'readyState=loaded' означает "скрипт загрузился", // а 'readyState=complete' -- "скрипт выполнился", но иногда // почему-то случается только одно из них, поэтому проверяем оба script.onreadystatechange = function() < if (this.readyState == 'complete' || this.readyState == 'loaded') < this.onreadystatechange = null; setTimeout(checkCallback, 0); // Вызвать checkCallback - после скрипта >> // события script.onload/onerror срабатывают всегда после выполнения скрипта script.onload = script.onerror = checkCallback; script.src = url; document.body.appendChild(script); >
function ok(data) < alert( "Загружен пользователь " + data.name ); >function fail(url) < alert( 'Ошибка при запросе ' + url ); >// Внимание! Ответы могут приходить в любой последовательности! scriptRequest("user?id=123", ok, fail); // Загружен scriptRequest("/badurl.js", ok, fail); // fail, 404 scriptRequest("/", ok, fail); // fail, 200 но некорректный скрипт

Демо, по нажатию на кнопке запускаются запросы выше:

var CallbackRegistry = <>; // реестр // при успехе вызовет onSuccess, при ошибке onError function scriptRequest(url, onSuccess, onError) < var scriptOk = false; // флаг, что вызов прошел успешно // сгенерировать имя JSONP-функции для запроса var callbackName = 'cb' + String(Math.random()).slice(-6); // укажем это имя в URL запроса url += ~url.indexOf('?') ? '&' : '?'; url += 'callback=CallbackRegistry.' + callbackName; // ..и создадим саму функцию в реестре CallbackRegistry[callbackName] = function(data) < scriptOk = true; // обработчик вызвался, указать что всё ок delete CallbackRegistry[callbackName]; // можно очистить реестр onSuccess(data); // и вызвать onSuccess >; // эта функция сработает при любом результате запроса // важно: при успешном результате - всегда после JSONP-обработчика function checkCallback() < if (scriptOk) return; // сработал обработчик? delete CallbackRegistry[callbackName]; onError(url); // нет - вызвать onError >var script = document.createElement('script'); // в старых IE поддерживается только событие, а не onload/onerror // в теории 'readyState=loaded' означает "скрипт загрузился", // а 'readyState=complete' -- "скрипт выполнился", но иногда // почему-то случается только одно из них, поэтому проверяем оба script.onreadystatechange = function() < if (this.readyState == 'complete' || this.readyState == 'loaded') < this.onreadystatechange = null; setTimeout(checkCallback, 0); // Вызвать checkCallback - после скрипта >> // события script.onload/onerror срабатывают всегда после выполнения скрипта script.onload = script.onerror = checkCallback; script.src = url; document.body.appendChild(script); >
var http = require('http'); var url = require('url'); var static = require('node-static'); var file = new static.Server('.', < cache: 0 >); function accept(req, res) < var urlParsed = url.parse(req.url, true); if (urlParsed.pathname == '/user') < var var callback = urlParsed.query.callback; res.setHeader('Content-Type', 'application/javascript; charset=utf-8'); var user = < name: "Вася", id: id >; res.end(callback + '(' + JSON.stringify(user) + ')'); > else < file.serve(req, res); >> // ------ запустить сервер ------- if (!module.parent) < http.createServer(accept).listen(8080); >else
        

COMET

COMET через SCRIPT реализуется при помощи длинных опросов, также как мы обсуждали в главе COMET с XMLHttpRequest: длинные опросы.

Читайте также:  Топ обучающих платформ python

То есть, создаётся тег , браузер запрашивает скрипт у сервера и… Сервер оставляет соединение висеть, пока не появится, что сказать. Когда сервер хочет отправить сообщение – он отвечает, используя формат JSONP. И, тут же, новый запрос…

Источник

Response: json() method

The json() method of the Response interface takes a Response stream and reads it to completion. It returns a promise which resolves with the result of parsing the body text as JSON .

Note that despite the method being named json() , the result is not JSON but is instead the result of taking JSON as input and parsing it to produce a JavaScript object.

Syntax

Parameters

Return value

A Promise that resolves to a JavaScript object. This object could be anything that can be represented by JSON — an object, an array, a string, a number…

Examples

In our fetch JSON example (run fetch JSON live), we create a new request using the Request() constructor, then use it to fetch a .json file. When the fetch is successful, we read and parse the data using json() , then read values out of the resulting objects as you’d expect and insert them into list items to display our product data.

const myList = document.querySelector("ul"); const myRequest = new Request("products.json"); fetch(myRequest) .then((response) => response.json()) .then((data) =>  for (const product of data.products)  const listItem = document.createElement("li"); listItem.appendChild(document.createElement("strong")).textContent = product.Name; listItem.append(` can be found in $product.Location>. Cost: `); listItem.appendChild( document.createElement("strong"), ).textContent = `£$product.Price>`; myList.appendChild(listItem); > >) .catch(console.error); 

Specifications

Browser compatibility

BCD tables only load in the browser

See also

Found a content problem with this page?

This page was last modified on Jul 7, 2023 by MDN contributors.

Your blueprint for a better internet.

Источник

Оцените статью