MooTools [1] JavaScript Framework включает поддержку для обработки звонков и Ajax делает кодирования для Ajax намного проще, хотя Есть еще некоторые морщины. Возможно, самым важным преимуществом использования рамках MooTools для Ajax является то, что кросс-браузерные и так озабоченность по поводу обеспечения того, чтобы ваш код будет работать на всех браузерах может быть главным образом левой в одну сторону.
В следующем тексте вы узнаете, как разработать простое Ajax запрос-ответ пару использованием MooTools в Joomla! 1,5. Этот простой пример, то расширенные, чтобы справиться с из ответов последовательность сервера. Наконец, если вы используете Ajax для доступа к веб-службы в другой области, то вы будете сталкиваться с "ту же политику происхождения" в веб-браузерах и безопасный метод работы вокруг этот вопрос обсуждается.
Ajax клиентом кода с помощью MooTools
В типичном приложении Ajax вы хотите вывести некоторые данные с сервера, который может быть ваш собственный сайт Joomla или удаленной веб-службы, и обновление некоторых элементов на веб-страницу с данными, которые возвращает сервер. Есть три элемента типичная реализация Ajax:
* Элемент HTML, изменение государственной вызовет запрос Ajax.
* Еще один элемент HTML, где данные ответа будет размещен. Часто это покажет "Ajax загрузки" значок или сообщение, а ответа от сервера в настоящее время ожидает.
* Код Ajax JavaScript себя.
Начиная с первой из них, необходимо определить элемент на странице, которые будут вызывать запрос Ajax. Элемент должен быть идентифицирован уникальным идентификатором атрибута. Например, предположим, у вас есть раскрывающемся выберите окно на странице, и вы хотите сделать запрос Ajax всякий раз, когда пользователь изменяет выбранному элементу. Тогда вы должны обеспечить, чтобы выбрать элемент имеет уникальный идентификатор атрибута, как это:
<select name="drop-down" id="drop-down">
<option value="1">Item 1</option>
<option value="2">Item 2</option>
<option value="3">Item 3</option>
</select>
Вы можете сгенерировать этот список выбора программно с помощью класса JHTML так:
<?php
$options = array();
$options[] = JHTML::_( 'select.option', '1', 'Item 1' );
$options[] = JHTML::_( 'select.option', '2', 'Item 2' );
$options[] = JHTML::_( 'select.option', '3', 'Item 3' );
echo JHTML::_( 'select.genericlist', $options, 'drop-down' );
Во-вторых, необходимо добавить элемент HTML, который будет содержать вывод вызова Ajax. Это может быть соответствующим, размещены DIV, который также должен иметь уникальный идентификатор атрибута, как это:
<div id="ajax-container"></div>
Вы можете, конечно, использовать ID в селектор стиля вывода с помощью CSS.
В-третьих, необходимо добавить код JavaScript, который сделает запрос Ajax и место ответа на вывод на экран. Как правило, вы не должны беспокоиться о загрузке MooTools себя как это делается автоматически для вас Joomla, но иногда вы должны сделать это вручную, добавив следующий код:
<?php
JHTML::_( 'behavior.mootools' );
Есть много способов, чтобы добавить JavaScript код на выход из Joomla. Один из способов, что позволяет избежать комплекса цитировании, заключается в использовании PHP "Heredoc" синтаксис (см. [2] для более подробной информации) так:
<?php
$ajax = <<<EOD
/* <![CDATA[ */
Your JavaScript code goes here.
/* ]]> */
EOD;
$doc = & JFactory::getDocument();
$doc->addScriptDeclaration( $ajax );
Упаковка код JavaScript между / * <! [CDATA [* / и / *]]> * / позволяет JavaScript, который будет выводиться не вызывая проблем с валидаторов HTML.
Вы можете вставлять PHP переменных в Heredoc текст, окружая их в фигурные скобки, например:
<?php
$ajax = <<<EOD
/* <![CDATA[ */
This is some JavaScript code with {$this->embedded} PHP variable in it.
/* ]]> */
EOD;
$doc = & JFactory::getDocument();
$doc->addScriptDeclaration( $ajax );
Код JavaScript должны добавить обработчик событий для элементов, которые будут вызывать вызова Ajax. Это делается в MooTools использовании следующего вызова:
window.addEvent( 'domready', function() {
$('drop-down').addEvent( 'change', <function-declaration> );
});
где <function-declaration> это код JavaScript, который будет вызываться при состояние элемента определены как раскрывающийся
изменилось. Обратите внимание, что вы всегда должны задержка вызова AddEvent до DOM готова следующих загрузки страницы. Это делается, говоря window.addEvent повесить функцию Ajax AddEvent на onDomReady события.
Вы не должны повесить вызов Ajax на OnChange события, например, вы можете использовать OnClick как триггер.
<function-declaration>, Что вы будете добавлять будет экземпляра класса MooTools Аякс, выглядящий примерно так:
var a = new Ajax( {$url}, {
method: 'get',
update: $('ajax-container')
}).request();
где {$ URL} является переменной PHP содержащие URL для запроса Ajax. В этом примере обновления аргумент был использован, чтобы скопировать весь ответ от сервера в элемент Ajax-контейнера. Это быстрый и удобный, но очень часто вы хотите, чтобы процесс ответ в некотором роде, прежде чем показывать его пользователю. Как правило, ответ JSON в кодировке, и вы должны расшифровать ответ и
формат их соответствующим образом перед обновлением Ajax-контейнера. Для этого, используйте OnComplete аргумента объект Ajax, а не обновление аргумент.
var a = new Ajax( {$url}, {
method: 'get',
onComplete: <completion-function>
}).request();
где <completion-function> это функция JavaScript, которая будет вызвана, когда ответ от удаленного сервера получен. Как правило, эта функция будет обрабатывать сырые данные с сервера перед отправкой его в элемент Ajax-контейнера.
Ниже более полный пример функции Ajax, которая получает данные с сервера в формате JSON, декодирует его, то толкает данные ответ в Ajax-контейнера.
window.addEvent( 'domready', function() {
$('drop-down').addEvent( 'change', function() {
$('ajax-container').empty().addClass('ajax-loading');
var a = new Ajax( {$url}, {
method: 'get',
onComplete: function( response ) {
var resp = Json.evaluate( response );
// Other code to execute when the request completes.
$('ajax-container').removeClass('ajax-loading').setHTML( output );
}
}).request();
});
});
Обратите внимание, что в этом примере есть и некоторый код для добавления, а затем удалить, AJAX-загрузки CSS класс из элемента Ajax-контейнера. Как правило, наличие этого класса приведет к "вертушкой" графический элемент для загрузки в качестве фонового изображения, чтобы пользователь осознает, что система все еще жива.
Обработка на стороне сервера запросов Ajax
Серверная часть вашей реализации Ajax могут быть общественные веб-службы, в этом случае она уже написана для вас. Но если вам нужно написать код сервера слишком то имеет смысл на базу кода на Joomla Framework. Хотя это может быть заманчивым для реализации серверного кода вне Joomla, вы пропустите несколько важных функций безопасности, которые делают написание безопасного сервера Ajax код очень прост.
Обычно вы хотите, чтобы сервер отправить свой ответ в формате XML или JSON. Joomla 1,5 поддержку шаблон проектирования MVC делает это особенно легко устроить. Просто добавьте новый класс вид на просмотры каталог в файл с именем view.xml.php или view.json.php в зависимости от формата требуется. Иногда ответ, необходимые для конкретного запроса настолько прост, что создание нового представления, будет излишним. В этом случае нет никаких проблем в создании выход непосредственно в контроллер; не требуется зрения.
Создание JSON выходной
PHP имеет встроенные функции для кодирования и декодирования JSON данных. Вы можете кодировать данные, используя json_encode функции, например:
<?php
// Set up the data to be sent in the response.
$data = array( 'some data' );
// Output the JSON data.
echo json_encode( $data );
Json_encode функция может кодировать почти все типы данных, такие как строки, массивы и объекты, хотя вы, возможно, должны знать, что соответствующая функция json_decode будет возвращать только объект (и, возможно, ассоциативный массив).
Это хорошая практика, чтобы установить MIME-тип для выхода правильно. В некоторых случаях вы также можете изменить имя файла, предложил нечто иное, чем "index.php", что вы, вероятно, получите по умолчанию. В следующем примере предлагается имя файла меняется на название взгляд, с ". JSON" добавлено расширение.
<?php
// Set up the data to be sent in the response.
$data = array( 'some data' );
// Get the document object.
$document =& JFactory::getDocument();
// Set the MIME type for JSON output.
$document->setMimeEncoding( 'application/json' );
// Change the suggested filename.
JResponse::setHeader( 'Content-Disposition', 'attachment; filename="'.$view->getName().'.json"' );
// Output the JSON data.
echo json_encode( $data );
Формирование XML-выходной
Joomla поддерживает простой и достаточно эффективный класс, JSimpleXML, которые могут быть использованы для создания XML-выход, например, реализации Ajax. Однако, используя объектно-ориентированный XML генератор страдает недостатком, что она,
как правило, медленно и интенсивно работающих с памятью, хотя JSimpleXML является легкая реализация. Если ваши требования особенно сложным, непосредственно вывода XML в виде строки приведет к сокращению времени отклика и ниже сервера след.
Например, следующий код выведет документ XML, состоящая из корневой элемент, называемый <root>, содержащие <items> элемент, который сам содержит один или несколько элементов <item> с фактическими данными. Вам нужно будет настроить код, чтобы справиться с вашими требованиями данных.
<?php
$document =& JFactory::getDocument();
$document->setMimeEncoding( 'text/xml' );
// Output XML header.
echo '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
// Output root element.
echo '<root>' . "\n";
// Output the data.
echo "\t" . '<items>' . "\n";
if (!empty( $data )) {
foreach ($data as $datum) {
echo "\t\t" . '<item>' . "\n";
foreach ($datum as $key => $value) {
echo "\t\t\t" . '<' . $key . '>' . htmlspecialchars( $value ) . '</' . $key . '>' . "\n";
}
echo "\t\t" . '</item>' . "\n";
}
}
echo "\t" . '</items>' . "\n";
// Terminate root element.
echo '</root>' . "\n";
Обратите внимание, что данные должны быть переданы через htmlspecialchars чтобы HTML символы правильно избежал.
Отметим также, что в этом примере некоторых попытка была сделана на "довольно печати" выход XML с вкладками и возврата каретки. Это не является строго обязательным, и эти дополнительные символы могут быть удалены, если вы предпочитаете.
Обработка из последовательности ответов в MooTools Ajax
Легко забыть, что начальная "" в "Аякс" означает "асинхронных", что означает, что, как только пользователь инициировал запрос Ajax, она может свободно заниматься другими делами в пользовательский интерфейс, в том числе решений других запросов Ajax . Как
дизайнер веб-приложений вы должны принять во внимание, что ответы на эти запросы могут не поступать обратно в том же порядке они были сделаны. Если не взяться за это может иметь плачевные последствия для пользователей. Например, в типичной реализации Ajax, где пользователь выбирает страну из выпадающего списка стран, а затем представлен в раскрывающемся списке регионов в этой стране, вызов Ajax производится всякий раз, когда страна изменилась. Ответ на этот запрос будет список регионов в выбранной стране. Но предположим, что пользователь делает серию довольно быстрые изменения выбора, то, что проще сделать с помощью клавиатуры, что с помощью мыши. Скажите пользователь нажимает "U" ключ и первой страной, которая приходит это "Уганда". Это не то, что пользователь хочет, чтобы она попадает в "U" несколько раз, пока она не получает "Соединенное Королевство", а затем еще раз, чтобы получить один она действительно хотела: "Соединенные Штаты". Это вызывает целый ряд Ajax вызовов производится в последовательности, с последним из которых является призыв к "Соединенные Штаты". Но предположим, что ответ на ее "Соединенное Королевство" запрос задерживается по некоторым причинам. Это может быть связано с нагрузки на сервер, или он может быть недоступен для сетевой задержки. Но по какой причине, он прибыл после "Соединенные Штаты" ответ. Тогда пользователю будет предложен список "Соединенное Королевство" регионов, хотя ее выбор был "Соединенные Штаты".
Такое поведение явно нежелательно. Различные средства для этого были предложены, в том числе те, которые связаны с сервером выполнения просьб в строгом порядке (который игнорирует возможность того, что сетевой задержки на ответный матч может
по-прежнему вызывают ответы приехать обратно на клиента из последовательности).
Однако, решение, предложенное ниже имеет силу того, что довольно просто, он не требует никакого специального кодирования на сервере, и он справляется со всеми классами задержки ответа, независимо от их причины. Идея заключается в поддержании простой очереди, содержащий все запросы, которые были сделаны и только на выходе результаты в правильной последовательности, независимо от порядка, в котором они прибывают.
Там должно быть какой-то способ определить, является ли конкретный запрос был завершен или нет. Для этого вы можете расширить класс MooTools Ajax так:
// Extend the Mootools Ajax class.
Ajax = Ajax.extend({
initialize: function( url, options ) {
this.parent( url, options );
this.ready = false;
this.output = '';
},
onComplete: function() {
this.ready = true;
this.parent();
}
});
Это добавляет еще два свойства класса Ajax:
* ready это логическое значение, флаги ли ответ можно или нет, и
* output который используется для хранения ответ.
Имея расширенный класс Ajax, вам нужно создать простой механизм очереди провести запроса информации. Каждый новый запрос будет оттеснена на очереди и выполненных запросов будет извлекается из очереди. Весь фокус в том, чтобы убедиться, что если до завершения запроса старые запросы были завершены он остается в очереди и не удаляются из последовательности.
Очередь принимает форму простой массив, объявленный в глобальном масштабе:
var AJAX_QUEUE = [];
Window.addEvent код изменен так, чтобы объект Ajax помещается в очередь перед сделан запрос:
window.addEvent( 'domready', function() {
$('drop-down').addEvent( 'change', function() {
$( 'ajax-container' ).empty().addClass( 'ajax-loading' );
var url = 'index.php?option=com_component&args=whatever';
var a = new Ajax( url, {
method: 'get',
onComplete: function( response ){
// Ajax onComplete function code goes here.
}
});
AJAX_QUEUE.push( a );
a.request();
});
});
Затем вам нужно добавить дополнительный код для OnComplete функцию, которая будет завершена поп-запросов из очереди, но только в правильном порядке:
// Save the response in the Ajax object.
this.output = response;
// Process the request queue.
while ( AJAX_QUEUE.length ) {
// If the oldest request in the queue is not ready, do nothing.
if ( !AJAX_QUEUE[0].ready ) break;
// Pop the request from the queue.
r = AJAX_QUEUE.shift();
// Only output to document when queue is empty.
if ( !AJAX_QUEUE.length ) {
$('ajax-container').removeClass('ajax-loading').setHTML(r.output);
}
}
Заметим, что выход только помещены в документ, когда очередь, наконец, пустой, так что пользователь никогда не видит результатов промежуточных запросов.
Если у вас есть несколько полей Ajax на одной странице, то вам нужно, чтобы дать каждому из своих собственных очереди, но кодирования остается практически то же самое.
Как избежать веб-браузера же политику происхождения в приложениях Ajax
Если вам необходимо получить доступ к веб-сервис, используя Ajax, что работает на сервере, который не в домене, то вы будете сталкиваться с "ту же политику происхождения" [3], что поможет предотвратить получение данных из-за пределов собственный домен по соображениям безопасности. Там должно быть какой-то способ обойти это ограничение на те случаи, когда веб-сервис является доверенным.
Наиболее распространенный способ обойти ту же политику происхождения в реализации Ajax является получение доступа к удаленным веб-службы с помощью прокси работает в вашей области. Прокси-сервер использует библиотеку HTTP клиента (например, [4]) для доступа к удаленному серверу. Этот метод, как правило, достаточно простой, но более жестко, если удаленный сервер требует проверки подлинности или использует куки для отслеживания состояния между запросами. С положительной стороны, используя прокси обычно облегчает кэш Ajax ответы, что-то, что, как правило, довольно сложно.
Чтобы добавить простой прокси для компонента Joomla нужно просто добавить дополнительные задачи на контроллер. Следующий
код показывает примерно то, что это может выглядеть, с учетом статического клиента HTTP класс, называемый HttpClient с методом,
который будет запрашивать страницы с удаленного сервера.
<?php
/**
* Support cross-domain Ajax request by using the component as a proxy.
* To use this facility replace "option" with "type" and "task" with "request"
* in the query that would otherwise be sent to the remote server.
*/
function proxy()
{
$uri = & JFactory::getURI();
$query = $uri->getQuery( true );
$query['option'] = $query['type'];
unset( $query['type']);
unset( $query['task']);
if (isset( $query['request'] )) {
$query['task'] = $query['request'];
unset( $query['request']);
}
// Make the API call.
$response = httpClient::call( $query );
if ($response->status != '200') {
JError::raiseError( 500, JText::_( 'Remote server error' ) );
return false;
}
// And return the response.
echo $response->data;
jexit();
}
Этот пример также показывает, как обойти ситуацию, когда удаленный сервер также работает Joomla, в этом случае он потребует URL содержащий опции и задачи аргументы, которые могут не совпадать требуется прокси-сервер. Например, предположим, вы хотите сделать запрос Ajax на удаленном сервере, используя эту ссылку:
http://www.remoteserver.com/index.php?option=com_remotecomponent&task=remotetask&arg=something
Чтобы избежать той же политики происхождения вы послать запрос на прокси вместо использования этого URL:
http://www.localserver.com/index.php?option=com_localcomponent&task=proxy&type=com_remotecomponent&request=remotetask&arg=something
Вам нужно будет адаптировать этот код в соответствии с вашими конкретными требованиями, например, если вам нужно указать контроллер для достижения прокси.
Добавление куки и кэш поддержка остается в качестве упражнения для читателя.
