Во время учебы в колледже я использовал объекты XMLHttpRequest и их эквиваленты в мире Microsoft для выполнения вызовов Ajax, которые были отправлены на URL в том же домене. Но с появлением веб-сервисов и созданием множества гибридных приложений вызовы Ajax не ограничиваются одним доменом, а пересекаются с различными доменами. Когда происходит такое сокращение границ домена, выполнение вызова Ajax с использованием XMLHttpRequest завершится неудачей из-за мер безопасности, реализованных браузерами. Вот тогда и возникла идея JSON-P, т.е. JSON с Padding.
В этой статье я процитирую из разных источников информацию о JSON-P, а затем продолжу и буду реализовывать примеры, которые вызывают API-интерфейс Stackoverflow для получения неотвеченных вопросов с тегом «jsonp».
Что такое JSONP?
Я не собираюсь пересматривать его определение. Вместо этого я приведу его определение из разных источников:
С головы первого HTML5:
JSONP — это способ получения объектов JSON с помощью
script
тега. Это также способ извлечения данных (опять же, в форме объектов JSON), который позволяет избежать проблем безопасности того же происхождения, которые мы видели в XMLHttpRequest. JSONP — это данные JSON, заключенные в JavaScript; как правило, вызов функции.
Одним из таких механизмов, который может запрашивать междоменный контент, является
script
тег. В декабре 2005 года Боб Ипполито официально предложил JSONP (позже названный JSON-P или JSON-with-padding) как способ использовать это свойствоscript
тегов, чтобы иметь возможность запрашивать данные в формате JSON между доменами. JSON-P работает, создаваяscript
элемент (либо в разметке HTML, либо вставляя его в DOM через JavaScript), который запрашивает расположение удаленной службы данных. Ответ (загруженный контент «JavaScript») — это имя функции, предварительно определенной на запрашивающей веб-странице, причем передаваемый ей параметр является запрашиваемыми данными JSON. Когда сценарий выполняется, функция вызывается и передает данные JSON, позволяя запрашивающей странице получать и обрабатывать данные.
Из Википедии: http://en.wikipedia.org/wiki/JSONP
JSONP или «JSON with padding» — это метод связи, используемый в программах JavaScript, которые работают в веб-браузерах. Он предоставляет метод для запроса данных с сервера в другом домене, что запрещено обычными веб-браузерами из-за одной и той же политики происхождения.
Подводя итог, можно сказать, что JSONP — это метод связи, позволяющий извлекать данные из некоторого URL-адреса, а затем использовать script
тег для установления связи и JavaScript для обновления HTML.
Было много вопросов о том, насколько безопасен JSONP, но я не хочу вдаваться в эти обсуждения, так как это не основной мотив этого поста.
Теперь, позвольте мне показать JSONP в действии на простом примере.
Простой пример для JSONP
Для простого примера я воспользуюсь некоторыми ресурсами из главы о JSONP в книге Head First HTML5. Я собираюсь сделать вызов JSONP для ресурса Javascript, который, в свою очередь, вызывает функцию обратного вызова, объявленную в моем источнике Javascript.
Давайте посмотрим на источник HTML:
<html> <head> <title></title> <meta charset="UTF-8"> <script src="simple.js"></script> </head> <body> <h1>JSONP Simple Demo</h1> <!-- we will update the data here --> <div id="jsonp"></div> </body> </html>
Интересная вещь происходит в коде JavaScript.
//simple.js window.onload = function(){ //Get the head element. var head = document.getElementsByTagName("head")[0]; //url for the javascript resource for JSONP call. var url = "http://wickedlysmart.com/hfhtml5/chapter6/dog3.js"; //Appending the script tag to the head element. //This triggers a JSONP call to get the data. var scriptTag = document.createElement("script"); scriptTag.setAttribute("src",url); head.appendChild(scriptTag); } //Method invoked by JSONP function animalSays(animal){ var div = document.getElementById("jsonp"); div.innerHTML = animal.type +" says "+ animal.sound; }
«Http://wickedlysmart.com/hfhtml5/chapter6/dog3.js» содержит:
var animal = { "type": "dog", "sound": "woof" }; animalSays(animal);
Приведенный выше код JavaScript:
1. Создает объект JSON
2. Вызывает обратный вызов, передавая объект JSON.
Теперь вопрос в том, где animalSays
объявлен метод? Если вы внимательно посмотрели на simple.js, вы можете увидеть, что метод animalSays
был объявлен. Когда JavaScript в приведенном выше URL-адресе запрашивается с использованием техники JSONP путем динамического добавления script
, в браузере выполняется javascript, который содержит определение animalSays
метода.
animalSays
Метод возвращает объект JSON , а затем заполняет HTML с данными в объекте JSON.
Давайте посмотрим на лучший пример.
Доступ к API Stackoverflow с использованием JSONP
Подробную информацию о API Stackoverflow для вопросов без ответов можно найти здесь . URL-адрес для доступа к оставшимся без ответа вопросам с тегом «jsonp»: https://api.stackexchange.com/2.1/questions/unanseded?order=desc&sort=activity&tagged=jsonp&site=stackoverflow
Приведенный выше URL возвращает некоторые данные JSON, но как это помогает в использовании JSONP? Можно добавить другой параметр к указанному выше URL-адресу, называемый «обратный вызов», который будет принимать имя метода JavaScript, который будет вызываться после загрузки URL-адреса script
тегом.
Давайте посмотрим на код HTML:
//sflow.html <!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="sflow.js"></script> </head> <body> <div>Unanswered questions tagged 'jsonp'</div> <!-- placeholder for updating the questions --> <div id="questions"> </div> </body> </html>
Код JavaScript состоит из 2 частей:
- Часть 1: Загрузка URL, который содержит данные и вызов функции.
window.onload = function() { var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); var url = "https://api.stackexchange.com/2.1/questions/unanswered?" + "order=desc" + "&sort=activity" + "&tagged=jsonp" + "&site=stackoverflow" + "&callback=listUnansweredQuestions"; //The URL is loaded by including it in the script tag and adding to the DOM. script.setAttribute("src", url); head.appendChild(script); }
- Часть 2: Определение обратного вызова, который получает данные, а затем обновляет HTML
function listUnansweredQuestions(questions) { var div = document.getElementById("questions"); var ul = document.createElement("ul"); div.appendChild(ul); for (var i = 0; i < questions.items.length; i++) { var question = questions.items[i]; var li = document.createElement("li"); li.innerHTML = "<a href="+question.link+">"+question.title+"</a>"; ul.appendChild(li); } }
Полный код Javascript будет:
//sflow.js window.onload = function() { var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); var url = "https://api.stackexchange.com/2.1/questions/unanswered?" + "order=desc" + "&sort=activity" + "&tagged=jsonp" + "&site=stackoverflow" + "&callback=listUnansweredQuestions"; script.setAttribute("src", url); head.appendChild(script); } function listUnansweredQuestions(questions) { var div = document.getElementById("questions"); var ul = document.createElement("ul"); div.appendChild(ul); for (var i = 0; i < questions.items.length; i++) { var question = questions.items[i]; var li = document.createElement("li"); li.innerHTML = "<a href="+question.link+">"+question.title+"</a>"; ul.appendChild(li); } }
Выход для выше HTML и Javascript будет: Если у вас есть какие — либо вопросы , в под управлением любой из образца кода , показанного в посте выше, пожалуйста, свяжитесь через комментарии ниже.