2006-07-29
Обсудить на форуме
Вы можете также прочитать полную документацию к библиотеке.
Данное руководство описывает JsHttpRequest - кроссбраузерную и очень простую в
использовании AJAX-библиотеку с поддержкой AJAX-закачки файлов на сервер и многими другими возможностями. JsHttpRequest
изначально позиционировался как кроссбраузерный аналог XMLHttpRequest, но теперь
он стал самостоятельным инструментом для создания динамических web-страниц.
Библиотека использует JavaScript (ActiveX, DOM и XMLHttpRequest, если последний
доступен) в frontend-е и PHP в backend-е.
Вот краткий список наиболее интересных возможностей и преимуществ библиотеки.
- Поддержка и "прозрачная" работа с любыми кодировками (windows-1251, koi8-r и UTF-8 работают даже без iconv или mbstring).
- Загрузка файлов на сервер "методом AJAX".
- Отличная кроссбраузерность (библиотека работает даже в IE 5.0 с отключенным ActiveX).
- Полная совместимость с популярной JavaScript-библиотекой prototype.
- Полная поддержка отладочных возможностей и традиционных методов программирования на PHP.
- Обмен многомерными структурами между клиентом и сервером (ассоциативные массивы).
- Автоматический выбор подходящего метода загрузки данных (XMLHttpRequest, <SCRIPT>, <IFRAME>).
- Доступен интерфейс, совместимый с XMLHttpRequest.
Учтите, что эта статья - только краткий обзор. Если вы хотите большего, пожалуйста,
обратитесь к следующим документам:
Что такое AJAX, backend и frontend?
AJAX
(Asynchronous Javascript And XML, Асинхронный JavaScript и XML), "Web 2.0" - это технологии, которые предполагают более
полное использование возможностей современных браузеров (к примеру, XMLHttpRequest и DOM). AJAX-библиотека
JsHttpRequest позволяет, например, делать подзапросы к веб-серверу без перезагрузки страницы.
Вы можете запросить данные с сервера и незамедлительно отобразить их в каком-нибудь блоке на странице.
Хорошим примером использования технологии AJAX является Google Suggest
(http://www.google.com/webhp?complete=1&hl=en):
|

Рис 1. Google Suggest. Вы вписываете запрос и получаете список результатов незамедлительно, без перезагрузки страницы.
|
Каждая веб-страница с AJAX состоит из двух частей: frontend и backend. В frontend вы делаете
запросы к веб-страницам, а в backend вы отвечаете на эти запросы.
|

Рис 2. Клиент-серверная организация AJAX-запросов
|
|
Frontend всегда выполняется в браузере.
Backend всегда выполняется на сервере.
|
Во frontend-е мы обычно пишем код на JavaScript, который передает информацию серверу. Например, так:
-
Листинг 1: отправка запроса
|
// Send a query.
JsHttpRequest.query(
"/ajax/suggester", // backend address
{ query: search_string.value }, // parameters
function(result, errors) {
// This function will be called when result is ready.
// Suggest the most popular word as query.
autocomplete_query(result["first"]["name"]);
// Draw "suggestions" to query.
show_suggestions (result);
}
); |
В backend-е мы можем использовать код на PHP, чтобы послать ответ на запрос. Мы напишем
что-то вроде следующего:
Листинг 2: обработка запроса
|
// Some functions that work with a database.
include "suggestions.lib.php";
// Get the query result.
$query = $_REQUEST["query"];
$result = get_suggestions($query);
// Give a name to the first element of result.
$result["first"] = $result[0];
$GLOBALS['_RESULT'] = $result; // $_RESULT will be passed to frontend |
Как вы могли заметить, в нашем коде нет ничего особенного. Правда, мы пока не говорили
о методе query() и не объясняли, как результат посылается обратно. Но нам больше не нужно писать
код самим, т.к. на сцену выходит JsHttpRequest.
Что предлагает библиотека JsHttpRequest?
AJAX-библиотека JsHttpRequest предлагает очень удобный интерфейс для написания как backend-,
так и frontend-скриптов. Вы можете посмотреть, как это работает, прямо тут. Напишите что-нибудь
(например, "тест") в следующем поле и подождите пару секунд, либо нажмите Enter, чтобы увидеть
результат немедленно:
Если вы хотите сделать подзапрос на сервер с использованием JsHttpRequest, вам всего лишь
понадобится вызвать метод JsHttpRequest.query():
Листинг 3: общий формат вызова библиотеки
|
// Code for AJAX FRONTEND.
JsHttpRequest.query(
address, // the path to backend
data, // the JavaScript array with data you want to pass
onreadyfunc(result, errors), // the function is called when an answer is ready
nocache // if set to TRUE, caching will be disabled
); |
Как вы можете видеть, в этой функции нет ничего лишнего:
нам всегда нужно указывать путь до backend-а (их ведь может быть несколько),
мы всегда передаем какие-то данные на сервер, и мы всегда реагируем на ответ сервера.
Заметьте, что мы не используем никакой код, зависящий от браузера пользователя.
Чтобы послать AJAX-ом файл, вам нужно:
- создать <form enctype="multipart/form-data">;
- поместить туда <input type="file" ... id="somefile">;
- в качестве значения передать узел DOM, соответствующий полю с выбором файла (вместо передачи строки, массива или числа);
- использовать что-то вроде { somefile: document.getElementById("somefile"); }.
(Подробности см. в примерах ниже.)
В backend-е вы получаете данные из массива $_REQUEST или $_FILES и сохраняете ответ в массив $_RESULT.
JsHttpRequest конвертирует JavaScript-массив data в PHP-массив $_REQUEST обычным для PHP способом
($_REQUEST - это стандартный массив входных данных в скриптах, которые не используют AJAX).
Библиотека также позволяет работать с массивом $_FILES, так что механизм загрузки файлов
стандартен для PHP.
|
Вы можете свободно передавать многомерные массивы как из backend-а, так и в backend.
|
Пример использования JsHttpRequest
Итак, давайте посмотрим пример!
Мы напишем полностью функционирующее AJAX-приложение, которое считает MD5 хэш-код
от введенной строки или содержимого выбранного файла. Конечно, мы будем использовать
JsHttpRequest.
|
MD5 - это популярная криптографическая функция, которая возвращает уникальный идентификатор для
любых переданных в нее строковых данных. При этом гарантируется, что даже для очень длинных и
несильно различающихся строк будут возвращены различные идентификаторы. (Точнее, совпадение
идентификаторов исчезающе маловероятно.) MD5 можно сравнить с отпечатками пальцев человека:
нельзя найти двух людей с абсолютно одинаковыми отпечатками.
|
FRONTEND (md5_frontend.htm)
Листинг 4: test/JsHttpRequest/md5_frontend.htm
|
<script src="../../lib/JsHttpRequest/JsHttpRequest.js"></script>
<script language="JavaScript">
// Function is called when we need to calculate MD5.
function calculate_md5() {
JsHttpRequest.query(
'md5_backend.php', // backend
{
// pass a text value
'str': document.getElementById("mystr").value,
// path a file to be uploaded
'upl': document.getElementById("myupl")
},
// Function is called when an answer arrives.
function(result, errors) {
// Write errors to the debug div.
document.getElementById("debug").innerHTML = errors;
// Write the answer.
if (result) {
document.getElementById("ans").innerHTML =
'MD5("' + result["str"] + '") = ' + result["md5"];
}
},
false // do not disable caching
);
}
</script>
<!-- Please note that we must specify enctype to multipart/form-data! -->
<form method="post" enctype="multipart/form-data" onsubmit="return false">
Enter a text: <input type="text" id="mystr"><br>
...or upload a file: <input type="file" id="myupl"><br>
<input type="button" value="Calculate MD5" onclick="calculate_md5()">
</form>
<div id="ans" style="border:1px solid #000; padding:2px">
Structured results
</div>
<div id="debug" style="border:1px dashed red; padding:2px">
Debug info
</div> |
Не пугайтесь размера frontend-а: мы просто не можем сделать его меньше, поскольку
пишем полностью функционирующее приложение.
|
Ассоциативные массивы в JavaScript создаются при помощи следующего синтаксиса:
my_js_array = { key1: value1, key2: value2, ... }
Доступ к элементам массива осуществляется с помощью конструкции my_js_array.key1 или my_js_array["key1"].
|
Вы можете также посмотреть пример работы frontend-а "вживую"
здесь.
BACKEND (md5_backend.php)
Листинг 5: test/JsHttpRequest/md5_backend.php
|
<?php
require_once "../../lib/JsHttpRequest/JsHttpRequest.php";
// Init JsHttpRequest and specify the encoding. It's important!
$JsHttpRequest =& new JsHttpRequest("windows-1251");
// Fetch request parameters.
$str = $_REQUEST['str'];
$upl = @$_FILES['upl'];
// Create the resulting array.
if (@$upl['tmp_name']) {
// The file was successfully uploaded.
$GLOBALS['_RESULT'] = array(
"str" => 'file ' . $upl['name'],
"md5" => md5(file_get_contents($upl['tmp_name'])),
);
} else {
// No file is uploaded, use the plain string.
$GLOBALS['_RESULT'] = array(
"str" => $str,
"md5" => md5($str),
);
}
// Everything we print will go to 'errors' parameter.
echo "<pre>";
?>
<b>QUERY_STRING:</b> <?=$_SERVER['QUERY_STRING'] . "\n"?>
<b>Uploaded files:</b> <?=print_r($_FILES, 1)?>
<?php
echo "</pre>";
// This includes a PHP fatal error! It will go to the debug stream,
// frontend may intercept this and act a reaction.
if ($_REQUEST['str'] == 'error') {
error_demonstration__make_a_mistake_calling_undefined_function();
}
?> |
Можно было бы ожидать, что backend будет очень больших размеров, но на самом деле это не так!
Нам ведь не нужно в нем заботиться, как информация будет выглядеть в браузере: это задача frontend-а.
Вы можете скачать архив demo.zip со всеми исходными кодами,
распаковать его в любом месте на вашем сайте и открыть http://your-site/path-to-demo/test/JsHttpRequest/md5_frontend.htm
в браузере. (Все примеры находятся в папке test/JsHttpRequest внутри распакованного архива.)
Работа совместно с библиотекой Prototype
Prototype это популярное средство для упрощения работы JavaScript-программиста, включающее поддержку AJAX и другие возможности. Библиотека JsHttpRequest может быть использована в качестве ее серверной PHP-части (после подключения небольшого модуля совместимости JsHttpRequest-prototype.js). При этом все дополнительные возможности, присущие JsHttpRequest (кроссбраузерность, закачка файлов, работа с русскими кодировками и т. д.), остаются в силе.
Листинг 6: Использование стандартных функций Prototype
|
<script src="../../lib/JsHttpRequest/JsHttpRequest.js"></script>
<script src="../../lib/JsHttpRequest/JsHttpRequest-prototype.js></script>
<script language="JavaScript">
new Ajax.Request('your_ajax_script.php', {
method: 'get',
parameters: {
name: 'Дмитрий',
file: $("my_upload_file")
},
onFailure: function(tr) {
alert('Error code: ' + tr.status + '\n');
alert(tr.responseText);
},
onSuccess: function(tr) {
$("result").innerHTML = tr.responseJS.hello;
if (tr.responseText) alert(tr.responseText);
}
});
</script> |
Конечно, вы можете использовать и любые другие возможности prototype для работы с AJAX (например, функции динамической подгрузки данных в HTML-элемент).
Резюме
Теперь вы знаете, как легко работать с AJAX при использовании JsHttpRequest.
Чтобы узнать, какие еще возможности есть у библиотеки (а их - масса!), рекомендуем
почитать следующие документы:
Автор библиотеки JsHttpRequest выражает благодарность Юрию Насретдинову за написание первой версии этой статьи.
|
|
|