Conditional GET with ETag and 304
Compute a strong ETag for a response body and answer If-None-Match with 304 Not Modified to save bandwidth.
- JavaScript
- GreenSnippets
- MIT
- Executed with Node.js 22
import { createHash } from "node:crypto";
function makeEtag(body) {
const hash = createHash("sha256").update(body).digest("base64url").slice(0, 27);
return `"${hash}"`;
}
function isNotModified(ifNoneMatch, etag) {
if (!ifNoneMatch) return false;
if (ifNoneMatch.trim() === "*") return true;
return ifNoneMatch.split(",").some((tag) => tag.trim().replace(/^W\//, "") === etag);
}
function respond(request, body) {
const etag = makeEtag(body);
const headers = { ETag: etag, "Cache-Control": "no-cache" };
if (isNotModified(request.headers.get("if-none-match"), etag)) {
return new Response(null, { status: 304, headers });
}
return new Response(body, { status: 200, headers });
}Example / expected output
// First request: 200 with ETag. Next request with If-None-Match: 304, empty body.How it works
An ETag is a fingerprint of a representation. Clients send it back in If-None-Match; if it still matches, the server replies 304 with no body. The comparison must tolerate a list of tags and the * wildcard. This sketch uses Node's crypto, and the same idea works in any framework.
Related snippets
- Python Tested
Cache function results with functools.lru_cache
Memoize pure functions with a bounded least-recently-used cache and inspect or clear it.
- JavaScript Tested
Parse the Link header for pagination
Extract next, prev, first and last page URLs from an RFC 8288 Link header like GitHub's API returns.
- Python Tested
Fetch JSON with the standard library
A small GET helper using urllib with a timeout, status check, size limit and JSON decoding errors.
- JavaScript Tested
Fetch every page of a paginated API with an async generator
Iterate cursor-paginated API results with for await, loading pages lazily and stopping early when needed.

