Ajax: The Name That Changed How We Think About the Web (2005)
On February 18, 2005, Jesse James Garrett at Adaptive Path published an essay titled "Ajax: A New Approach to Web Applications." It was not a technical breakthrough. XMLHttpRequest had been in Internet Explorer since 1999 as an ActiveX component. Mozilla had a native implementation since 2002. The specification was years old.
What Garrett did was give the pattern a name and articulate what it made possible. Before "Ajax," developers who used XMLHttpRequest were doing something unnamed and niche. After "Ajax," it was a recognized architectural approach with a vocabulary everyone could use.
Google Maps launched in February 2005. Gmail had launched in beta in April 2004. Both used XMLHttpRequest to update page content without reloading. After Garrett's essay, every developer in the industry understood why these products felt different - and wanted to build that way.
What the Ajax Pattern Actually Was
Garrett's definition was specific. Ajax was not just XMLHttpRequest. It was a combination:
- Standards-based presentation using XHTML + CSS
- Dynamic display and interaction using the Document Object Model
- Data interchange using XML and XSLT (JSON wasn't the default yet - that came later)
- Asynchronous data retrieval using XMLHttpRequest
- JavaScript binding everything together
The architectural shift: instead of the server rendering complete HTML pages on every request, the browser became a thin application layer. The server served data. The browser rendered it. The interaction loop was: user action → JavaScript → XMLHttpRequest → server response → DOM update. No page reload.
// The raw Ajax pattern, 2005 - before jQuery abstracted it
// This is what every developer wrote by hand
function ajax(options) {
var xhr;
// Cross-browser XHR creation - IE used ActiveX, others had native
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
// IE 5, 6
try { xhr = new ActiveXObject('MSXML2.XMLHTTP.6.0'); }
catch (e) { xhr = new ActiveXObject('Microsoft.XMLHTTP'); }
}
if (!xhr) {
options.error && options.error('XMLHttpRequest not available');
return;
}
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
if (xhr.status === 200) {
options.success && options.success(xhr.responseText);
} else {
options.error && options.error(xhr.status, xhr.statusText);
}
};
xhr.open(options.method || 'GET', options.url, true); // true = async
if (options.method === 'POST') {
xhr.setRequestHeader(
'Content-Type',
'application/x-www-form-urlencoded'
);
xhr.send(options.data || null);
} else {
// IE 6 cache-busting: it cached GET requests aggressively
var url = options.url;
if (url.indexOf('?') === -1) {
url += '?_t=' + new Date().getTime();
} else {
url += '&_t=' + new Date().getTime();
}
xhr.send(null);
}
}
// Usage - search with live results
ajax({
url: '/search.php?q=' + encodeURIComponent(query),
success: function(html) {
document.getElementById('search-results').innerHTML = html;
document.getElementById('loading').style.display = 'none';
},
error: function(status) {
alert('Search failed: ' + status);
}
});
A Real Ajax Feature: Live Search (2005)
The "live search" was the hello-world of Ajax in 2005. Type in a box - results appear without submitting a form:
// livesearch.js - 2005 implementation
// No debounce library. setTimeout by hand.
var searchTimer = null;
function initLiveSearch() {
var input = document.getElementById('search-input');
if (!input) return;
input.onkeyup = function() {
// Clear previous timer - debounce at 300ms
if (searchTimer) clearTimeout(searchTimer);
var query = input.value;
if (query.length < 2) {
document.getElementById('live-results').innerHTML = '';
return;
}
document.getElementById('live-results').innerHTML =
'<p class="loading">Searching...</p>';
searchTimer = setTimeout(function() {
performSearch(query);
}, 300);
};
}
function performSearch(query) {
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
document.getElementById('live-results').innerHTML = xhr.responseText;
}
};
// Server returns an HTML fragment, not a full page
xhr.open('GET',
'/search.php?q=' + encodeURIComponent(query) +
'&ajax=1&_t=' + new Date().getTime(),
true
);
xhr.send(null);
}
window.onload = initLiveSearch;
Server side (PHP returning an HTML fragment):
<?php
// search.php - 2005 server, handles both Ajax and full-page requests
$query = isset($_GET['q']) ? trim($_GET['q']) : '';
$is_ajax = isset($_GET['ajax']) && $_GET['ajax'] == '1';
if (strlen($query) < 2) {
if ($is_ajax) exit;
header('Location: /');
exit;
}
$q = mysql_real_escape_string($query);
$results = mysql_query(
"SELECT id, title, excerpt FROM posts
WHERE MATCH(title, content) AGAINST ('$q' IN BOOLEAN MODE)
AND published = 1
LIMIT 10"
);
if ($is_ajax) {
// Return only the results fragment - not the full HTML page
if (mysql_num_rows($results) === 0) {
echo '<p>No results for <em>' . htmlspecialchars($query) . '</em></p>';
exit;
}
echo '<ul class="search-results">';
while ($row = mysql_fetch_assoc($results)) {
echo '<li>';
echo '<a href="/post/' . $row['id'] . '">';
echo htmlspecialchars($row['title']);
echo '</a>';
echo '<p>' . htmlspecialchars($row['excerpt']) . '</p>';
echo '</li>';
}
echo '</ul>';
exit;
}
// Non-Ajax: render full page
include 'header.php';
// ... full page render
?>
The JSON Question: Why Were We Still Using XML?
In 2005, the "A" in Ajax officially stood for "Asynchronous" and the "X" for "XML." The original pattern used XML as the data format between client and server:
<!-- The XML response that "proper" Ajax was supposed to use -->
<?xml version="1.0" encoding="utf-8"?>
<results>
<post>
<id>42</id>
<title>Getting Started with Ajax</title>
<excerpt>Ajax changes everything about how web apps work...</excerpt>
</post>
</results>
// Parsing XML in JavaScript - painful in 2005
var xml = xhr.responseXML;
var posts = xml.getElementsByTagName('post');
for (var i = 0; i < posts.length; i++) {
var title = posts[i].getElementsByTagName('title')[0].firstChild.nodeValue;
// ...
}
In practice, most developers returned HTML fragments (as in the search example above) or started using a format Douglas Crockford had been promoting: JSON. JSON parsing in 2005 was eval() - there was no JSON.parse() until 2009 (ES5). But it was dramatically simpler than parsing XML DOM trees.
The shift from XML to JSON as the default Ajax data format happened between 2005 and 2008. By the time jQuery 1.0 shipped in August 2006, its $.getJSON() method made JSON the obvious default.
What 2005 Established
The year Ajax was named established that the browser was an application runtime, not a document viewer. This was not a new technical capability - it had existed since 1999. What changed was the mental model. Once developers understood the pattern and had a name for it, adoption was rapid.
By the end of 2005:
- Google Suggest was live and widely noticed
- Google Maps had changed user expectations for web interactivity
- Ruby on Rails 1.0 shipped with built-in Ajax helpers using
prototype.js - Every web framework was adding Ajax support
- Developers were asking "how do I make this not reload the page?" as a standard question
The web would never go back to full-page reload as the default interaction model.
Aunimeda builds production-grade backend systems - APIs, microservices, real-time applications, and system integrations.
Contact us for backend engineering services. See also: Custom Software Development, Web Development