JSONP — это метод передачи данных JSON, не заботясь о кросс-доменных ограничениях.
В JSONP не используется объект XMLHttpRequest.
Вместо этого JSONP использует тег <script>.
Введение
JSONP означает "JSON with padding" (JSON с набивкой) и является дополнением к формату JSON.
Запрос данных с сервера, находящегося в другом домене, может вызвать определенные проблемы из-за политики ограничения домена.
Запрос же внешних скриптов с сервера, находящегося в другом домене, не вызывает таких проблем.
JSONP пользуется этим преимущество, запрашивая файлы при помощи тега <script> вместо объекта XMLHttpRequest.
<script src="//msiter.ru/demo_jsonp.php">
Файл на сервере
Файл на сервере оборачивает данные в вызов функции:
<?php
$myJSON = '{ "name":"John", "age":30, "city":"New York" }';
echo "myFunc(".$myJSON.");";
?>
В результате возвращается вызов к функции с именем "myFunc" с данными JSON в качестве параметра.
Внимание! Такая функция должна существовать в клиентском скрипте.
JavaScript функция
Функция с именем "myFunc" находится в клиентском скрипте и предназначена для обработки данных JSON:
function myFunc(myObj) {
document.getElementById("demo").innerHTML = myObj.name;
}
Создание динамического тега <script>
Предыдущий пример будет выполнять функцию "myFunc", когда страница полностью загрузится, основываясь на том, где расположен тег <script>, что не удовлетворительно.
Тег <script> должен создаваться только при необходимости.
В следующем примере тег <script> создается и вставляется в HTML код при нажатии на кнопку:
function clickButton() {
var s = document.createElement("script");
s.src = "demo_jsonp.php";
document.body.appendChild(s);
}
Динамический результат JSONP
Приведенные выше примеры все еще очень статичны.
Сделаем пример динамическим, посылая данные JSON файлу php и получая объект JSON на основе заданной информации.
PHP файл:
<?php
header("Content-Type: application/json; charset=UTF-8");
$obj = json_decode($_GET["x"], false);
$conn = new mysqli("myServer", "myUser", "myPassword", "Northwind");
$result = $conn->query("SELECT name FROM ".$obj->$table." LIMIT ".$obj->$limit);
$outp = array();
$outp = $result->fetch_all(MYSQLI_ASSOC);
echo "myFunc(".json_encode($outp).")";
?>
Объяснение PHP файла:
- Преобразуем запрос в объект при помощи PHP функции json_decode().
- Обратимся к базе данных и заполним массив полученной информацией.
- Добавим массив к объекту.
- Преобразуем массив в формат JSON при помощи функции json_encode().
- Обернем "myFunc()" вокруг возвращаемого объекта.
Пример JavaScript
Функция "myFunc" будет вызываться из php файла:
function clickButton() {
var obj, s
obj = { "table":"products", "limit":10 };
s = document.createElement("script");
s.src = "jsonp_demo_db.php?x=" + JSON.stringify(obj);
document.body.appendChild(s);
}
function myFunc(myObj) {
var x, txt = "";
for (x in myObj) {
txt += myObj[x].name + "<br>";
}
document.getElementById("demo").innerHTML = txt;
}
Функция обратного вызова
А как настроить серверный файл для вызова нужной функции, если нет доступа к файлам на сервере?
Иногда серверный файл в качестве параметра предоставляет функцию обратного вызова.
В следующем примере php файл будет вызывать функцию, которую вы передаете в качестве параметра обратного вызова:
function clickButton() {
var s = document.createElement("script");
s.src = "jsonp_demo_db.php?callback=myDisplayFunction";
document.body.appendChild(s);
}