JSONP

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);
 }