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

17

У меня возникли проблемы с пониманием того, как работает 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?

    
задан John Baum 17.04.2012 в 16:22
источник
  • возможный дубликат Пожалуйста, объясните JSONP –  Jon 17.04.2012 в 16:27

3 ответа

40

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

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

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

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

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

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

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

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

на странице.

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

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

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

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

 internalUseOnlyFunction('deleteHarddrive');

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

    
ответ дан Marc B 17.04.2012 в 16:31
источник
  • Я бы не стал так далеко, как deleteHardDrive (javascript не может сделать это из браузера), но определенно стоит отметить, что это может быть опасно. –  hitautodestruct 12.11.2013 в 14:48
  • Отличное объяснение! –  FloatingRock 19.09.2014 в 18:10
1

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

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

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

function parseResponse(data) {
    console.log("JSONP request complete", data);
}
    
ответ дан Alex Turpin 17.04.2012 в 16:29
источник
  • Каким образом возвращаемые данные волшебным образом становятся параметром для функции parseRepsonse? –  John Baum 17.04.2012 в 16:30
  • @JohnBaum, потому что сервер создает код JS, который будет вызываться? –  Alex Turpin 17.04.2012 в 17:10
0
  

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

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

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

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

function parseResponse(data){
    console.log(data);
}
    
ответ дан JKirchartz 17.04.2012 в 16:29
источник