Что такое JSONP и чем он отличатеся от JSON
JSON - это просто формат данных. JSONP - это методология использования этого формата в кросс-доменных запросах.
JSONP - это старый трюк, придуманный для обхода ограничения безопасности в веб-браузерах, которое запрещает нам получать данные, находящиеся на другом сайте/сервере.
JSONP расшифровывается как JSON with Padding.
JSONP запрос
Идея заключается в том, что вместо использования ajax для запроса данных, мы используем тег <script src="externalURL">
. В src указанном в скрипте наша страница получает и запускает JS код.
Сервер на который был отправлен такой запрос должен отдать нам правильный JS код (JSONP ответ). В этом ответе сервер вместо JSON стоки, отдает JS код, где JSON данные передаются как параметр функции (какое название будет у функции мы указываем в URL). На своей стороне мы создаем JS функцию, которая по итогу будет запущена после того как придет ответ с удаленного сервера.
Получается что при загрузке и выполнении скрипта у нас запускается js функция, где первый параметр - это JSON объект полученный с удаленного сервера. В этой функции мы и обрабатываем полученные с другого сервера данные.
Рассмотрим на примере
Допустим, наш домен example.com и мы хотим сделать запрос на домен example.net. Для этого нам нужно пересечь границы нашего домена, а это запрещено в большинстве браузеров. Единственный элемент, который обходит это ограничение - это тег <script>
.
Когда мы делаем запрос на сервер (через тег <script>), который поддерживает JSONP, мы передаем специальный параметр, который сообщает серверу название нашей JS функции, которую нужно запустить. Таким образом, удаленный сервер может завернуть свой JSON в функцию и вернуть там готовый JS код, который будет запущен на нашей странице.
Допустим, сервер ожидает параметр _jsonp
, чтобы включить JSONP. Тогда наш URL (запрос) будет выглядеть следующим образом:
http://www.example.net/sample.aspx?_jsonp=myCallback
Без ?_jsonp=myCallback
сервер бы вернул JSON строку, например:
{ "foo": "bar" }
Однако, когда сервер получает параметр "_jsonp", он расценивает запрос как JSONP и формирует результат по-другому, возвращая:
myCallback( { foo: "bar" } );
На своей странице мы создаем такую функцию-обработчик:
function myCallback( data ){ alert( data.foo ) }
Теперь, когда скрипт будет загружен - он будет выполнен у нас, т.е. сработает наша js функция с данными JSON от удаленного сервера.
Вуаля, кросс-доменный запрос выполнен!
Пример кода с JSONP запросом
Базовый пример JavaScript (лента Twitter с использованием JSONP)
<html> <head> ... </head> <body> <div id="twitterFeed"></div> <script> function myCallback( dataWeGotViaJsonp ){ var text = '' var len = dataWeGotViaJsonp.length for( var i=0; i<len; i++ ){ twitterEntry = dataWeGotViaJsonp[i]; text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>' } document.getElementById('twitterFeed').innerHTML = text; } </script> <script src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script> </body> </html>
Проблемы (недостатки)
-
С JSONP у нас нет нормального контроля над запросом. Например, не существует нормального способа получить код ошибки. В результате нам, например, нужно будет использовать таймеры для контроля запроса и т.д.
-
Использование JSONP небезопасно. Поскольку JSONP - это фактически javascript, он может делать все, что может делать javascript, поэтому мы должны полностью доверять поставщику данных JSONP, потому что мы запускаем чужой JS-код, который может быть изменен на вредоносный в любой момент.
- Мы можем выполнять только GET-запросы.
Есть предложение JSONRequest, которое вроде как должно решить проблему меж-доменных запросов, безопасности и обеспечения надлежащего контроля над запросом.
Рекомендация - Не используйте JSONP, используйте CORS
Сегодня CORS является рекомендуемым подходом для выполнения кросс-доменных запросов. JSONP все еще полезен для поддержки старых браузеров, но, учитывая безопасность - CORS - лучший выбор.
Кроме того, политика безопасности Same-Origin применяется не только к JSON данным, но и к любым другим: WebFonts, изображения/видео, нарисованные с помощью drawImage()...
Читайте о CORS здесь: https://developer.mozilla.org/ru-RU/docs/Web/HTTP/CORS Суть коротко:
Cross-Origin Resource Sharing (CORS) - это механизм, который использует дополнительные HTTP-заголовки, чтобы сообщить браузерам о предоставлении веб-приложению, запущенному в одном месте, доступа к выбранным ресурсам из другого места.
Веб-приложение выполняет кросс-доменный HTTP-запрос всегда, когда запрашивает ресурс, который имеет отличное от его собственного происхождение (домен, протокол или порт).
WordPress функции связанные с JSONP
- wp_is_jsonp_request()
- Проверяет, является ли текущий запрос запросом JSONP или ожидает ответа JSONP.
- wp_check_jsonp_callback()
- Checks that a JSONP callback is a valid JavaScript callback name.
- _jsonp_wp_die_handler()
- Kills WordPress execution and displays JSONP response with an error message.