AJAX - Conditional AJAX Requests with ETag and Last-Modified
Conditional AJAX requests are a technique used to reduce unnecessary data transfer between a web browser and a server. In a normal AJAX request, the browser asks the server for a resource, and the server sends the complete response even when the requested data has not changed. With conditional requests, the browser can tell the server which version of the resource it already has. The server then checks whether the resource has changed. If there is no change, the server can respond without sending the complete resource again. This saves bandwidth, reduces server workload, and can improve application performance.
ETag
An ETag, or Entity Tag, is a unique identifier assigned by a server to a particular version of a resource. The value usually changes whenever the resource changes. For example, suppose an AJAX application requests a JSON file containing product information. The server might return the data along with an ETag such as "abc123". The browser can store this ETag together with the response.
When the browser makes another request for the same resource, it can send the previously received ETag in the If-None-Match request header. The server compares this value with the current ETag of the resource. If both values match, the server knows that the resource has not changed. It can then return an HTTP 304 Not Modified response instead of sending the complete data again.
A simplified request sequence looks like this:
First AJAX request
Browser → Server
GET /products.json
Server → Browser
200 OK
ETag: "abc123"
Product data
Later:
Second AJAX request
Browser → Server
GET /products.json
If-None-Match: "abc123"
Server → Browser
304 Not Modified
The browser can then continue using its previously stored copy of the data.
Last-Modified
Last-Modified is another method for determining whether a resource has changed. Instead of assigning a version identifier, the server tells the browser when the resource was last modified.
For example:
Last-Modified: Mon, 05 Oct 2026 08:00:00 GMT
The browser can remember this date. During a later request, it sends the date using the If-Modified-Since request header:
If-Modified-Since: Mon, 05 Oct 2026 08:00:00 GMT
The server compares the supplied date with the resource's current modification time. If the resource has not changed since that time, the server returns:
304 Not Modified
If the resource has changed, the server returns the updated resource with a normal successful response, generally 200 OK.
ETag and Last-Modified Difference
Both mechanisms have the same basic purpose, but they identify changes differently.
| Feature | ETag | Last-Modified |
|---|---|---|
| Identifies | Specific version of a resource | Modification time |
| Request header | If-None-Match |
If-Modified-Since |
| Server response when unchanged | 304 Not Modified |
304 Not Modified |
| Accuracy | Generally more precise | Based on modification time |
| Useful for | Precise version validation | Simple time-based validation |
ETags can be useful when a resource may change without its modification time providing sufficiently precise information. Last-Modified is simpler and can be useful when the server already maintains reliable modification timestamps.
Using Conditional Requests with AJAX
AJAX itself does not require a separate JavaScript mechanism for ETag or Last-Modified. These features are part of HTTP caching and conditional request processing. An AJAX request made using XMLHttpRequest or other browser APIs can participate in normal HTTP caching behavior.
For example, an AJAX request can be made using XMLHttpRequest:
const xhr = new XMLHttpRequest();
xhr.open("GET", "products.json", true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log("Updated data received");
console.log(xhr.responseText);
} else if (xhr.status === 304) {
console.log("Data has not changed");
}
}
};
xhr.send();
In practice, browsers and HTTP caching mechanisms may automatically manage conditional requests depending on the response headers and cache state. Developers therefore generally configure appropriate caching behavior on the server rather than manually implementing the entire ETag mechanism in JavaScript.
Example in an AJAX Application
Consider a school website that uses AJAX to retrieve a list of courses. The course list may remain unchanged for several hours.
During the first request, the server sends:
HTTP/1.1 200 OK
ETag: "courses-v15"
Content-Type: application/json
The browser receives the course data and stores the response according to the applicable caching rules.
Later, when the application needs the course list again, a conditional request may contain:
If-None-Match: "courses-v15"
If the server determines that the course list is still version courses-v15, it responds:
HTTP/1.1 304 Not Modified
No new copy of the JSON data needs to be transferred. The browser can use its cached representation.
If a new course has been added, the server may now have:
ETag: "courses-v16"
Because "courses-v15" does not match "courses-v16", the server sends the updated course list:
HTTP/1.1 200 OK
ETag: "courses-v16"
followed by the new JSON data.
Advantages
Conditional AJAX requests provide several important benefits. The first is reduced bandwidth consumption because unchanged resources do not need to be transferred repeatedly. This can be particularly useful for applications that frequently request the same information.
The second benefit is improved performance. When a resource has not changed, the server can return a small 304 Not Modified response rather than transferring a potentially large response body.
The third benefit is reduced server workload. Although the server still needs to determine whether the resource has changed, it does not have to generate and transfer the complete response in many cases.
Another benefit is better scalability. Applications with many users repeatedly requesting common resources can reduce unnecessary network traffic and data transfer by making effective use of HTTP caching and conditional requests.
Important Considerations
ETag and Last-Modified are most effective when the server sends appropriate HTTP cache headers and correctly validates conditional requests. Developers should also understand that a 304 Not Modified response does not mean that the browser receives no useful result. It means that the server is telling the client that the previously cached representation is still valid.
Developers should also avoid treating ETags as permanent identifiers. An ETag represents a particular version of a resource and can change whenever the server considers the resource representation to have changed.
Conclusion
Conditional AJAX requests using ETag and Last-Modified allow web applications to determine whether previously retrieved data is still current before transferring the complete resource again. ETag uses a version identifier, while Last-Modified uses a modification timestamp. When the server determines that the resource has not changed, it can return 304 Not Modified, allowing the browser to reuse its existing cached response. This approach can reduce bandwidth usage, improve response efficiency, lower unnecessary data transfer, and make AJAX-based applications more efficient.