Может ли кто-нибудь объяснить, что такое JSONP, в условиях неспециалиста?

Я знаю, что JSONP есть JSON с заполнением.

Я понимаю, что такое JSON, и как его использовать с jQuery.getJSON(). Тем не менее, я не понимаю концепцию callback при введении JSONP.

Может ли кто-нибудь объяснить мне, как это работает?

Ответ 1

Введение:

Этот ответ старше шести лет. Хотя концепции и применение JSONP не изменились (т.е. подробности ответа остаются в силе), вы должны попробуйте использовать CORS, где это возможно (т.е. ваш server или API поддерживает его, и поддержка браузера является адекватной), поскольку JSONP имеет встроенные риски безопасности.


JSONP (JSON с Padding) - это метод, обычно используемый для обходите междоменные политики в веб-браузерах. (Вы не можете делать запросы AJAX на веб-страницу, воспринимаемую браузером на другом сервере.)

JSON и JSONP ведут себя по-разному на клиенте и на сервере. Запросы JSONP не отправляются с использованием методов XMLHTTPRequest и связанных браузеров. Вместо этого создается тэг <script>, источник которого установлен на целевой URL. Этот тег script затем добавляется в DOM (обычно внутри элемента <head>).

Запрос JSON:

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
    // success
  };
};

xhr.open("GET", "somewhere.php", true);
xhr.send();

Запрос JSONP:

var tag = document.createElement("script");
tag.src = 'somewhere_else.php?callback=foo';

document.getElementsByTagName("head")[0].appendChild(tag);

Разница между ответом JSON и ответом JSONP заключается в том, что объект ответа JSONP передается как аргумент функции обратного вызова.

JSON:

{ "bar": "baz" }

JSONP:

foo( { "bar": "baz" } );

Вот почему вы видите запросы JSONP, содержащие параметр callback, чтобы сервер знал имя функции, чтобы обернуть ответ.

Эта функция должна существовать в глобальной области в момент, когда тег <script> оценивается браузером (после завершения запроса).


Еще одно отличие от обработки ответа JSON и ответа JSONP заключается в том, что любые ошибки синтаксического анализа в ответе JSON могут быть пойманы путем обертывания попытки оценить responseText в заявлении try/catch. Из-за характера ответа JSONP ошибки синтаксического анализа в ответе будут приводить к необратимой ошибке синтаксического анализа JavaScript.

Оба формата могут реализовать ошибки тайм-аута, установив тайм-аут перед началом запроса и сброса таймаута в обработчике ответа.


Полезность использования jQuery для создания запросов JSONP заключается в том, что jQuery делает всю работу для вас в фоновом режиме.

По умолчанию jQuery требует включить &callback=? в URL вашего запроса AJAX. jQuery будет использовать указанную success функцию, присвоить ей уникальное имя и опубликовать ее в глобальной области. Затем он заменит знак вопроса ? в &callback=? на имя, которое оно присвоило.


Сопоставимые реализации JSON/JSONP

Следующее предполагает объект ответа { "bar" : "baz" }

JSON:

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
    document.getElementById("output").innerHTML = eval('(' + this.responseText + ')').bar;
  };
};

xhr.open("GET", "somewhere.php", true);
xhr.send();

JSONP:

function foo(response) {
  document.getElementById("output").innerHTML = response.bar;
};

var tag = document.createElement("script");
tag.src = 'somewhere_else.php?callback=foo';

document.getElementsByTagName("head")[0].appendChild(tag);

Ответ 2

Скажите, что у вас есть URL-адрес, который дал вам данные JSON, например:

{'field': 'value'}

... и у вас был аналогичный URL, за исключением того, что он использовал JSONP, которому вы передали имя функции обратного вызова 'myCallback' (обычно это делается путем предоставления ему параметра запроса, называемого обратным вызовом, например http://example.com/dataSource?callback=myCallback). Затем он вернется:

myCallback({'field':'value'})

... который является не просто объектом, а на самом деле является кодом, который может быть выполнен. Поэтому, если вы определите функцию в другом месте на вашей странице под названием myFunction и выполните этот script, она будет вызываться с данными из URL-адреса.

Приятная вещь: вы можете создать тег script и использовать свой URL (в комплекте с параметром callback) в качестве атрибута src, и браузер запустит его. Это означает, что вы можете обойти политику безопасности "того же самого происхождения" (поскольку браузеры позволяют запускать теги script из других источников, кроме домена страницы).

Это то, что делает jQuery, когда вы делаете запрос ajax (используя .ajax с 'jsonp' в качестве значения для dataType имущество). Например.

$.ajax({
  url: 'http://example.com/datasource',
  dataType: 'jsonp',
  success: function(data) {
    // your code to handle data here
  }
});

Здесь jQuery позаботится о имени функции обратного вызова и параметре запроса, что делает API идентичным другим вызовам ajax. Но в отличие от других типов запросов ajax, как уже упоминалось, вы не ограничены получением данных из того же источника, что и ваша страница.

Ответ 3

JSONP - это способ обойти браузер политика одного и того же происхождения. Как? Вот так:

введите описание изображения здесь

Цель состоит в том, чтобы сделать запрос в otherdomain.com и alert имя в ответе. Обычно мы делаем запрос AJAX:

$.get('otherdomain.com', function (response) {
  var name = response.name;
  alert(name);
});

Однако, поскольку запрос отправляется в другой домен, он не будет работать.

Мы можем сделать запрос, используя тег <script>. Оба <script src="otherdomain.com"></script> и $.get('otherdomain.com') приведут к тому же запросу:

GET otherdomain.com

Q: Но если мы используем тег <script>, как мы можем получить доступ к ответу? Нам нужно получить к нему доступ, если мы хотим alert его.

A: Мы не можем. Но вот что мы можем сделать - определить функцию, которая использует ответ, а затем сообщить серверу ответить JavaScript, который вызывает нашу функцию с ответом в качестве аргумента.

Q: Но что, если сервер не сделает этого для нас и только хочет вернуть нам JSON?

A: Тогда мы не сможем его использовать. JSONP требует, чтобы сервер работал.

В: Использование тега <script> является уродливым.

A: Библиотеки, такие как jQuery делают это лучше. Пример:

$.ajax({
    url: "http://otherdomain.com",
    jsonp: "callback",
    dataType: "jsonp",
    success: function( response ) {
        console.log( response );
    }
});

Он работает путем динамического создания элемента DOM тега <script>.

Q: теги <script> обрабатывают только запросы GET - что делать, если мы хотим сделать запрос POST?

A: Тогда JSONP не будет работать для нас.

Q: Это нормально, я просто хочу сделать запрос GET. JSONP потрясающе, и я собираюсь использовать его - спасибо!

A: На самом деле, это не удивительно. Это действительно просто хак. И это не самая безопасная вещь для использования. Теперь, когда CORS доступен, вы должны использовать его, когда это возможно.

Ответ 4

Я нашел полезную статью, которая также объясняет эту тему вполне понятным и понятным языком. Ссылка JSONP

Некоторые из заслуживающих внимания пунктов:

  • Предварительные даты JSONP CORS.
  • Это псевдостандартный способ получения данных из другого домена,
  • Он имеет ограниченные возможности CORS (только метод GET)

Работа выполняется следующим образом:

  • <script src="url?callback=function_name"> включен в html-код
  • Когда выполняется шаг 1, он воспринимает функцию с тем же именем функции (как указано в параметре url) в качестве ответа.
  • Если функция с указанным именем существует в коде, она будет выполнена с данными, если они есть, возвращены в качестве аргумента этой функции.