Ответ 1
Чтобы полностью понять, почему чистый междоменный XML не будет работать, он помогает сначала посмотреть, как облегчается междоменный JSON.
Во-первых, давайте посмотрим, что произойдет, когда вы выполните запрос AJAX в jQuery:
$.ajax({
url: '/user.php?userId=123',
success: function(data) {
alert(data); // alerts the response
});
В приведенном выше примере запрос AJAX сделан относительно домена. Мы знаем, что если мы попытаемся добавить другой путь до пути, запрос завершится с исключением безопасности.
Однако это не означает, что браузер не может отправлять запросы другому домену. Вот пример, который вам может быть знаком:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
Основываясь на наших знаниях о том, как импортировать JavaScript на странице, мы видим, что можно загрузить ресурс, который существует в другом домене!
JSONP - это концепция, которая использует это знание. JSONP означает "JSON with padding", и успех этого успеха зависит от того, что объекты JavaScript могут быть выражены с использованием строковой нотации, а также то, что теги JavaScript script могут загружать и запускать контент из внешних доменов.
Под капотом jQuery JSONP выглядит примерно так, хотя это может быть и не так:
// programmatically load a script tag on the page using the given url
function loadRemoteData(url) {
var script = document.createElement("script");
script.setAttribute("type","text/javascript");
script.setAttribute("src", url);
document.getElementsByTagName("head")[0].appendChild(script);
}
Кроме того, на странице где-то мы определяем обработчик обратного вызова:
function processData(jsonResult) {
alert(JSON.stringify(jsonResult)); //alert the JSON as a string
}
Здесь мы делаем запрос:
// make a request for the data using the script tag remoting approach.
loadRemoteData("http://example.com/users.php?userId=123&callback=processData");
Для того, чтобы это правильно работало, наш PHP script должен как вернуть данные в формате JSON, так и добавить "дополнение" вокруг строки в виде имени функции JavaScript, которое мы можем передать в качестве параметра (т.е. "обратный вызов" )
Таким образом, ответ с сервера может выглядеть примерно так, если бы мы посмотрели его на вкладке Firebug или Chrome NET:
processData( { "userId" : "123" , "name" : "James" , "email" : "[email protected]" } );
Поскольку мы знаем, что содержимое JavaScript запускается сразу после его загрузки, наша функция processData
, которую мы определили ранее, немедленно вызывается и передается нашей строкой JSON в качестве параметра. Затем он предупреждается, используя JSON.stringify для преобразования объекта обратно в строку.
Так как это объект, я мог бы также получить доступ к его свойствам, например:
function processData(jsonResult) {
alert(JSON.stringify(jsonResult)); //alert the JSON as a string
// alert the name and email
alert("User name is " + jsonResult.name + " and email is " + jsonResult.email);
}
Наконец, перейдем к основному вопросу: Может ли JSONP использоваться для извлечения XML или мы можем проанализировать XML-домен? Ответ, как указывали другие, - это громкое НЕТ, но давайте посмотрим, почему, используя пример:
processData(<?xml version="1.0"><user><userid>12345</userid><name>James</name><email>[email protected]</email></user>);
Теперь, что произойдет, если исходный XML будет передан в функцию? Он сломается, поскольку JavaScript не имеет возможности преобразовать XML в JSON.
Однако предположим, что мы помещаем XML в кавычки:
processData("<?xml version="1.0"><user><userid>12345</userid><name>James</name><email>[email protected]</email></user>");
Теперь в этом примере переменная jsonResult фактически принимает строку, с которой мы можем работать. Используя некоторые утилиты для анализа XML JavaScript, мы могли бы загрузить эту строку в XML DOM Parser и делать с ней все!
Однако, это не чистый XML, это еще ответ JavaScript под капотом. Тип ответа с сервера PHP по-прежнему является текстовым /javascript, и мы все еще используем тег script для загрузки того, что на самом деле является просто обычным JavaScript.
В общем, вы можете работать с XMLP или XML с дополнением (я только что сделал это, это не реально!), но если вы собираетесь решить все проблемы, связанные с фактическим изменением вашего ответа на возврат вы можете просто преобразовать свой вывод в JSON и позволить браузеру обрабатывать преобразования автоматически и изначально и избавить себя от необходимости использовать XML-парсер.
Но если по какой-то причине проще хранить данные в формате XML, вы можете изменить ответ и дать ему оболочку JavaScript.
Случаи, когда я мог бы заметить, что это полезно, могут быть, если у вас есть данные XML из устаревшего приложения, хранящиеся в базе данных, и вы возвращаете его на стороне клиента, используя script -tag remoting или JSONP-вызовы.