Подтвердить что ты не робот

Смутно, как работает запрос JSONP

У меня возникли проблемы с пониманием того, как работает jsonp-запрос. Я прочитал несколько источников, в том числе wiki, на jsonp, и я все еще очень смущен тем, как обратный вызов фактически захватывает функцию, возвращаемую с сервера при вызове jsonp. Например, в wiki источник запроса устанавливается как:

src="http://server2.example.com/RetrieveUser?UserId=1234&jsonp=parseResponse"

Что именно делает jsonp = parseResponse на самом деле/​​означает? Затем они говорят, что полезная нагрузка:

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});

Как это работает? Я запутался во всей функции обратного вызова. Имя функции parseResponse передается на сервер, и каким-то образом возвращаемые данные становятся параметрами для этой функции? Может кто-то, пожалуйста, четко объяснить, как данные извлекаются/используются из запроса jsonp?

4b9b3361

Ответ 1

Обратный вызов - это функция, которую вы определили в своем собственном коде. Сервер jsonp будет обернуть свой ответ вызовом функции с именем, аналогичным указанной функции обратного вызова.

Что происходит:

1) Ваш код создает запрос JSONP, в результате чего создается новый блок <script>, который выглядит следующим образом:

<script src="http://server2.example.com/RetrieveUser?UserId=1234&jsonp=parseResponse"></script>

2) Новый тэг script выполняется вашим браузером, что приводит к запросу на сервер JSONP. Он отвечает

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});

3) Поскольку этот запрос поступает из тега script, он в значительной степени ТОЧНО так же, как если бы вы буквально разместили

<script>
    parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});
</script>

на странице.

4) Теперь, когда этот новый script был загружен с удаленного сервера, он будет выполнен, и единственное, что он будет делать, это вызов функции parseResponse(), передающий данные JSON в качестве функции только для вызова.

Итак, где-то еще в вашем коде у вас будет:

function parseResponse(data) {
     alert(data.Name); // outputs 'Foo'
}

В принципе, JSONP - это способ обхода политики безопасности браузера с одинаковым исходным кодом script, путем подключения стороннего сервера к вызову функции непосредственно на вашу страницу. Обратите внимание, что это по дизайну очень небезопасно. Вы зависите, что удаленная служба почетна и не имеет злонамеренных намерений. Ничто не останавливает плохой сервис от возврата какого-либо JS-кода, который крадет ваши банковские/фейсбуки/любые учетные данные. например.... ответ JSONP мог быть

 internalUseOnlyFunction('deleteHarddrive');

а не parseReponse (...). Если удаленный сайт знает структуру вашего кода, он может выполнять произвольные операции с этим кодом, потому что вы открыли открытую переднюю дверь, чтобы этот сайт мог делать все, что захочет.

Ответ 2

Изменить: Как сказал Джон, для него есть более удобное объяснение здесь.

JSONP использует теги script для запросов на кросс-поиск. Поскольку тег script используется для включения сценариев, сервер должен возвращать действительный JavaScript. Способ, которым мы предоставляем JavaScript клиенту, - это вызов функции. Вы сообщаете серверу, какую функцию вы хотите вызвать script, и затем создаете эту функцию локально. Когда выполняется script, ваша функция будет вызываться с данными в качестве параметра.

Итак, если вы выполнили запрос JSONP по указанному вами URL-адресу, и он возвратил полезную нагрузку, о которой вы упомянули, вы можете перейти к своим данным, выполнив следующие действия:

function parseResponse(data) {
    console.log("JSONP request complete", data);
}

Ответ 3

Имя функции parseResponse передается на сервер и как-то возвращаемые данные становятся параметрами для этой функции

Похоже, вы сами это объяснили, jsonp=parseResponse заключается в том, как это приложение устанавливает функцию обратного вызова, поэтому он возвращает функцию с вашими json-данными в ней, которая выглядит как

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});

который вызывается при его загрузке и будет обрабатываться функцией в вашем JS, например:

function parseResponse(data){
    console.log(data);
}