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