Что такое JSONP и чем он отличатеся от JSON

Click here to view original web page at wp-kama.ru

JSON - это просто формат данных. JSONP - это методология использования этого формата в кросс-доменных запросах.

JSONP - это старый трюк, придуманный для обхода ограничения безопасности в веб-браузерах, которое запрещает нам получать данные, находящиеся на другом сайте/сервере.

JSONP расшифровывается как JSON with Padding.

Идея заключается в том, что вместо использования ajax для запроса данных, мы используем тег <script src="externalURL">. В src указанном в скрипте наша страница получает и запускает JS код.

Сервер на который был отправлен такой запрос должен отдать нам правильный JS код (JSONP ответ). В этом ответе сервер вместо JSON стоки, отдает JS код, где JSON данные передаются как параметр функции (какое название будет у функции мы указываем в URL). На своей стороне мы создаем JS функцию, которая по итогу будет запущена сервером.

Получается что при загрузке и выполнении скрипта у нас запускается js функция, где первый параметр - это JSON объект полученный с удаленного сервера. В этой функции мы и обрабатываем полученные с другого сервера данные.

Допустим, наш домен example.com и мы хотим сделать запрос на домен example.net. Для этого нам нужно пересечь границы нашего домена, а это запрещено в большинстве браузеров. Единственный элемент, который обходит это ограничение - это тег <script>.

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

Допустим, сервер ожидает параметр _jsonp, чтобы включить JSONP. Тогда наш URL (запрос) будет выглядеть следующим образом:

http://www.example.net/sample.aspx?_jsonp=myCallback

Без ?_jsonp=myCallback сервер бы вернул базовый объект JavaScript, например:

{ foo: 'bar' }

Однако, когда сервер получает параметр "_jsonp", он расценивает запрос как JSONP и формирует результат по-другому, возвращая:

myCallback( { foo: 'bar' } );

На своей странице мы создаем такую функцию:

function myСallback( data ){
	alert( data.foo )
}

Теперь, когда скрипт будет загружен - он будет выполнен и у нас сработает наша js функция с данными JSON от удаленного сервера.

Вуаля, кросс-доменный запрос выполнен!

Базовый пример 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, которое вроде как должно решить проблему меж-доменных запросов, безопасности и обеспечения надлежащего контроля над запросом.

Сегодня 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-запрос всегда, когда запрашивает ресурс, который имеет отличное от его собственного происхождение (домен, протокол или порт).

wp_is_jsonp_request()
Проверяет, является ли текущий запрос запросом JSONP или ожидает ответа JSONP.
Checks that a JSONP callback is a valid JavaScript callback name.
Kills WordPress execution and displays JSONP response with an error message.