Вопрос по ajax, javascript – Запутался в том, как работает запрос JSONP

20

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

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

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

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

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

возможный дубликатPlease explain JSONP Jon

Ваш Ответ

3   ответа
0

the data returned becomes parameters to this function

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

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

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

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

которую вы определяете в своем собственном коде. Сервер 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, который крадет ваши банковские / Facebook / любые учетные данные. например, ответ JSONP мог быть

 internalUseOnlyFunction('deleteHarddrive');

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

Я бы не пошел так далеко, как примерdeleteHardDrive (javascript не может сделать это из браузера), но определенно стоит отметить, что это может быть опасно.
Отличное объяснение!
1

Edit: Как сказал Джон, этому есть лучшее объяснениеВот.

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

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

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

Похожие вопросы