До Ajax казахстанские веб-разработчики строили сайты по одной модели: пользователь нажимает - страница перезагружается. Форма отправлена - полная перезагрузка. Поиск - полная перезагрузка. Добавить в корзину - перезагрузка. Это было нормально, потому что так работал весь веб.
Google Maps изменил это в феврале 2005. Карта, которую можно перетаскивать. Которая загружает новые тайлы без перезагрузки. Которая отвечает немедленно. Пользователи в Алматы, открывшие Google Maps, понимали: это не обычный сайт.
Технология называлась XMLHttpRequest и существовала в IE с 1999 года. Джесси Гаррет в феврале 2005 дал ей имя: Ajax. Имя изменило всё.
Живой поиск: первый Ajax для Казнета
// livesearch.js - 2005 год
// jQuery не существовал. Всё вручную.
// Для казахстанских сайтов: поиск по товарам, статьям, компаниям
var searchTimer = null;
function initSearch() {
var input = document.getElementById('search');
if (!input) return;
input.onkeyup = function() {
if (searchTimer) clearTimeout(searchTimer);
var q = input.value;
if (q.length < 2) {
document.getElementById('results').innerHTML = '';
return;
}
// Debounce: ждём 400мс после последнего нажатия
searchTimer = setTimeout(function() {
runSearch(q);
}, 400);
};
}
function runSearch(query) {
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest(); // Firefox, Opera, Safari
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP'); // IE 5/6
}
// В Казнете 2005 году IE 6 занимал 70%+ рынка
// Оба варианта были обязательны
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
document.getElementById('results').innerHTML = xhr.responseText;
}
};
// IE агрессивно кешировал GET - добавляем timestamp
var url = '/search.php?q=' + encodeURIComponent(query)
+ '&ajax=1&t=' + Date.now();
xhr.open('GET', url, true);
xhr.send(null);
}
window.onload = initSearch;
Серверная часть: PHP + MySQL
<?php
// search.php - серверная часть поиска
// Казнет 2005: типичный LAMP-стек
$q = isset($_GET['q']) ? trim($_GET['q']) : '';
$is_ajax = isset($_GET['ajax']) && $_GET['ajax'] == '1';
if (mb_strlen($q, 'UTF-8') < 2) {
if ($is_ajax) exit;
header('Location: /');
exit;
}
$q_safe = mysql_real_escape_string($q);
// Поиск по товарам, названиям компаний и т.д.
$result = mysql_query(
"SELECT id, name, description
FROM catalog
WHERE (name LIKE '%$q_safe%'
OR description LIKE '%$q_safe%')
AND active = 1
LIMIT 8",
$conn
);
if ($is_ajax) {
if (mysql_num_rows($result) === 0) {
echo '<p class="no-results">Ничего не найдено</p>';
exit;
}
echo '<ul class="search-results">';
while ($row = mysql_fetch_assoc($result)) {
echo '<li>';
echo '<a href="/item/' . (int)$row['id'] . '">';
echo htmlspecialchars($row['name']);
echo '</a>';
echo '<span>' . htmlspecialchars(substr($row['description'], 0, 60)) . '...</span>';
echo '</li>';
}
echo '</ul>';
exit;
}
// Не-Ajax: полная страница
include 'header.php';
// ...
?>
JSON вместо XML
// 2005: "A" в Ajax = Asynchronous, "X" = XML
// Но на практике казахстанские разработчики сразу выбирали JSON
// XML-ответ - болезненно:
var xml = xhr.responseXML;
var items = xml.getElementsByTagName('item');
// Пара строк кода на каждый элемент...
// JSON через eval() - до JSON.parse (ES5, 2009):
var data = eval('(' + xhr.responseText + ')');
// Небезопасно при недоверенных данных.
// Но работало. И было в 10 раз проще XML.
// PHP-сторона:
// echo json_encode($array); // появился в PHP 5.2 (2006)
// В 2005 - вручную: echo '{"name":"' . $name . '"}';
Ajax в Казнете: 2005-2007
Первые Ajax-элементы на казахстанских сайтах появились в 2005-2006: живой поиск на порталах, автодополнение в формах, подгрузка контента без перезагрузки.
К 2007 году jQuery сделал Ajax тривиальным - $.ajax() вместо ручного XHR. Казахстанские разработчики массово начали использовать jQuery именно для Ajax-запросов.
Ajax изменил ожидания пользователей. После Google Maps и Gmail пользователи в Алматы стали ожидать отзывчивости от веб-сайтов. Сайты, которые перезагружались на каждое действие, начали казаться устаревшими. Веб стал конкурировать с нативными приложениями.