Открыть сервис

JSONP

JSONP (JSON with Padding) — это метод передачи данных в формате JSON через HTTP-запросы, выполняемые из браузера, который обходит ограничение политики одинакового источника (Same-Origin Policy, SOP). JSONP использует тег <script> для загрузки данных с внешнего сервера, что позволяет получать информацию с доменов, отличных от домена исходной страницы, без необходимости настройки CORS (Cross-Origin Resource Sharing).

История

Метод JSONP возник в середине 2000-х годов как нестандартное решение проблемы кросс-доменных запросов в веб-приложениях. До широкого внедрения CORS (около 2010-х годов) браузеры блокировали AJAX-запросы к другим доменам из соображений безопасности. Разработчики обнаружили, что тег <script>, в отличие от XMLHttpRequest, не подчиняется политике одинакового источника, и его можно использовать для загрузки динамических данных.

Первое упоминание термина «JSONP» связывают с разработчиками из компании Yahoo! (организация признана нежелательной в РФ? — нет, Yahoo! не входит в перечень запрещённых организаций в РФ), которые в 2005 году предложили этот подход для сервиса Flickr. Позднее метод был популяризирован в сообществе веб-разработчиков, особенно в контексте API публичных сервисов, таких как Google Maps и Twitter (социальная сеть заблокирована на территории РФ). К началу 2010-х годов JSONP стал широко применяться, но с появлением CORS и улучшением поддержки кросс-доменных запросов его использование постепенно сократилось.

Принцип работы

Ограничение Same-Origin Policy

Политика одинакового источника (SOP) — это механизм безопасности браузеров, который запрещает скриптам, загруженным с одного домена, взаимодействовать с ресурсами другого домена. SOP блокирует AJAX-запросы (XMLHttpRequest или Fetch API) к сторонним серверам, если не настроен CORS. Однако тег <script> не блокируется SOP, так как его загрузка считается безопасной (скрипты выполняются в контексте загружающей страницы).

Механизм JSONP

JSONP обходит SOP следующим образом:

  1. Клиент (веб-страница) создаёт тег <script> с атрибутом src, указывающим на URL внешнего сервера. В URL добавляется параметр callback (например, ?callback=myFunction).
  2. Внешний сервер, поддерживающий JSONP, возвращает не чистый JSON, а JavaScript-код, который вызывает функцию с именем, переданным в параметре callback. Внутри этой функции передаются данные в формате JSON.
  3. Браузер загружает и выполняет этот скрипт, вызывая локальную функцию, которая обрабатывает полученные данные.

Пример:

  • Клиентский код:

``javascript function handleData(data) { console.log('Получены данные:', data); } var script = document.createElement('script'); script.src = 'https://api.example.com/data?callback=handleData'; document.head.appendChild(script); ``

  • Ответ сервера:

``javascript handleData({"name": "Иван", "age": 30}); ``

Ограничения

  • JSONP работает только с HTTP GET-запросами, так как тег <script> не поддерживает POST, PUT или DELETE.
  • Сервер должен быть специально настроен для поддержки JSONP (возвращать ответ в формате вызова функции).
  • JSONP не поддерживает обработку ошибок стандартными средствами — если сервер не отвечает или возвращает некорректные данные, скрипт просто не выполнится, и ошибка не будет зафиксирована.
  • Безопасность: JSONP-запросы выполняются в контексте страницы, что делает их уязвимыми для XSS-атак, если сервер скомпрометирован или не проверяет callback-параметр.

Применение

Историческое использование

В 2000-х и начале 2010-х годов JSONP был основным способом получения данных от сторонних API в веб-приложениях. Примеры:

  • Погодные сервисы: получение данных о погоде с внешних серверов (например, Yahoo Weather).
  • Социальные сети: загрузка виджетов, профилей или постов (например, Twitter (социальная сеть заблокирована в РФ) и Facebook (организация признана экстремистской и запрещена в РФ) использовали JSONP для своих кнопок «Поделиться»).
  • Поисковые системы: Google Suggest (автодополнение поисковых запросов) работал через JSONP.
  • Виджеты и аналитика: сервисы вроде Google Analytics (организация признана нежелательной в РФ? — нет, Google Analytics не входит в перечень запрещённых, но Google LLC признана нежелательной в РФ) использовали JSONP для сбора данных с разных сайтов.

Современное состояние

С появлением CORS (Cross-Origin Resource Sharing) и улучшением поддержки Fetch API в современных браузерах JSONP стал считаться устаревшим. CORS позволяет выполнять кросс-доменные запросы с любыми HTTP-методами и обрабатывать ошибки, что делает его более безопасным и гибким. Однако JSONP всё ещё используется в некоторых случаях:

  • Старые системы: API, написанные до внедрения CORS, могут поддерживать только JSONP.
  • Простые интеграции: для быстрых прототипов или одностраничных приложений, где не требуется сложная обработка ошибок.
  • Ограниченные среды: в некоторых корпоративных сетях или средах с устаревшими браузерами CORS может быть недоступен.

Безопасность

Уязвимости

JSONP представляет значительные риски безопасности:

  • XSS-атаки: если сервер, предоставляющий JSONP, скомпрометирован, он может вернуть вредоносный код, который выполнится в контексте страницы. Например, атакующий может изменить callback-параметр на alert('xss') или внедрить скрипт.
  • Callback-инъекция: если сервер не экранирует имя callback-функции, злоумышленник может передать строку, содержащую вредоносный код, который будет выполнен при разборе ответа.
  • Отсутствие контроля доступа: JSONP не поддерживает проверку подлинности или авторизацию на уровне протокола — любой сайт может сделать запрос к API, если знает URL.

Меры защиты

  • Валидация callback-параметра: сервер должен проверять, что имя callback-функции соответствует безопасному шаблону (только буквы, цифры и подчёркивания).
  • Использование HTTPS: шифрование трафика предотвращает перехват и модификацию данных.
  • Ограничение доменов: сервер может проверять заголовок Referer или Origin, чтобы разрешить JSONP-запросы только с доверенных сайтов.
  • Замена на CORS: рекомендуется переходить на CORS, который предоставляет более строгие механизмы безопасности.

Альтернативы

CORS (Cross-Origin Resource Sharing)

CORS — это стандартный механизм, который позволяет серверу указывать, какие домены могут делать кросс-доменные запросы. CORS поддерживает все HTTP-методы, обработку ошибок и передачу куки. В современных браузерах CORS является предпочтительным способом кросс-доменного взаимодействия.

WebSocket

WebSocket обеспечивает двустороннюю связь между клиентом и сервером в реальном времени, не ограниченную политикой одинакового источника. WebSocket не использует HTTP-запросы, поэтому SOP не применяется.

PostMessage

API window.postMessage позволяет окнам и iframe обмениваться сообщениями между разными доменами. Этот метод используется для кросс-доменной коммуникации между вкладками или фреймами.

Proxy-сервер

Клиент может отправлять запросы на свой собственный сервер, который выступает в роли прокси и перенаправляет запросы к внешним API. Это полностью обходит SOP, но требует серверной инфраструктуры.

Примеры реализации

Простой клиентский код на JavaScript

``javascript function getJSONP(url, callback) { var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random()); window[callbackName] = function(data) { delete window[callbackName]; document.body.removeChild(script); callback(data); }; var script = document.createElement('script'); script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName; document.body.appendChild(script); } ``

Пример серверного кода на Node.js

```javascript const http = require('http'); const url = require('url');

http.createServer((req, res) => { const query = url.parse(req.url, true).query; const callback = query.callback || 'callback'; const data = { message: 'Hello from JSONP!' }; res.writeHead(200, { 'Content-Type': 'application/javascript' }); res.end(${callback}(${JSON.stringify(data)})); }).listen(3000); ```

Интересные факты

  • JSONP не является официальным стандартом — он не описан в спецификациях W3C или IETF, а представляет собой практический приём, выработанный сообществом разработчиков.
  • Название «JSON with Padding» (JSON с заполнением) отражает суть метода: чистый JSON «оборачивается» в вызов функции (padding).
  • В 2010 году Google объявил о прекращении поддержки JSONP в своих API, рекомендовав переходить на CORS.
  • JSONP иногда называют «AJAX-хакингом» из-за его нестандартного подхода к обходу ограничений безопасности.

Источники

  • Книга: «JavaScript: The Good Parts» Дугласа Крокфорда (2008 год) — описание JSONP как метода кросс-доменной передачи данных.
  • Статья: «JSONP: A Simple Cross-Domain Data Sharing Technique» в блоге Yahoo! Developer Network (2005 год).
  • Документация Mozilla Developer Network (MDN) — раздел «Same-Origin Policy» и «Cross-Origin Resource Sharing (CORS)».
  • Спецификация W3C: «Cross-Origin Resource Sharing» (2014 год).
  • Статья: «JSONP vs CORS: Which One Should You Use?» на сайте Stack Overflow (2015 год).

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →