Bird
Raised Fist0
Node.jsframework~5 mins

ETag and conditional requests in Node.js

Choose your learning style10 modes available
Introduction

ETags help servers and browsers check if content has changed. This saves data by only sending updates when needed.

When you want to reduce data sent between server and browser for faster loading.
When your website has static files like images or scripts that rarely change.
When you want to improve user experience by loading pages faster.
When you want to save bandwidth on your server.
When you want to implement caching in your Node.js web app.
Syntax
Node.js
res.setHeader('ETag', etagValue);

if (req.headers['if-none-match'] === etagValue) {
  res.statusCode = 304;
  res.end();
} else {
  res.statusCode = 200;
  res.end(content);
}

The ETag header is a unique string representing the content version.

The If-None-Match header is sent by the browser to check if the content changed.

Examples
Sends 'Hello World' only if content changed; otherwise sends 304 Not Modified.
Node.js
const etagValue = '12345';
res.setHeader('ETag', etagValue);

if (req.headers['if-none-match'] === etagValue) {
  res.statusCode = 304;
  res.end();
} else {
  res.statusCode = 200;
  res.end('Hello World');
}
Generates ETag using MD5 hash of content for better uniqueness.
Node.js
const crypto = require('crypto');
const content = 'My content';
const etagValue = crypto.createHash('md5').update(content).digest('hex');
res.setHeader('ETag', etagValue);

if (req.headers['if-none-match'] === etagValue) {
  res.statusCode = 304;
  res.end();
} else {
  res.statusCode = 200;
  res.end(content);
}
Sample Program

This Node.js server sends an ETag header based on the content's SHA-256 hash. If the browser sends the same ETag back, the server replies with 304 Not Modified, saving data.

Node.js
import http from 'http';
import crypto from 'crypto';

const server = http.createServer((req, res) => {
  const content = 'Welcome to my site!';
  const etagValue = crypto.createHash('sha256').update(content).digest('hex');

  res.setHeader('ETag', etagValue);

  if (req.headers['if-none-match'] === etagValue) {
    res.statusCode = 304;
    res.end();
  } else {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end(content);
  }
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});
OutputSuccess
Important Notes

ETags should be unique for each content version to work correctly.

304 status means 'Not Modified' and tells the browser to use cached content.

Always set Content-Type header when sending content.

Summary

ETags help browsers know if content changed to avoid re-downloading.

Use If-None-Match header to check ETag from browser requests.

Respond with 304 status to save bandwidth when content is unchanged.

Practice

(1/5)
1. What is the main purpose of using an ETag in HTTP responses in Node.js?
easy
A. To set the cache expiration time
B. To encrypt the response data for security
C. To specify the content type of the response
D. To help browsers check if the content has changed and avoid re-downloading unchanged data

Solution

  1. Step 1: Understand what ETag represents

    ETag is a unique identifier for a specific version of a resource, used to detect changes.
  2. Step 2: Identify its role in HTTP caching

    Browsers use ETag to check if the resource changed since last download, avoiding unnecessary data transfer.
  3. Final Answer:

    To help browsers check if the content has changed and avoid re-downloading unchanged data -> Option D
  4. Quick Check:

    ETag purpose = avoid re-download [OK]
Hint: ETag means "same content? skip download" [OK]
Common Mistakes:
  • Confusing ETag with encryption
  • Thinking ETag sets content type
  • Mixing ETag with cache expiration headers
2. Which of the following is the correct way to set an ETag header in a Node.js HTTP response?
easy
A. res.setHeader('ETag', '12345')
B. res.header('etag', 12345)
C. res.etag = '12345'
D. res.set('ETag', 12345)

Solution

  1. Step 1: Recall Node.js HTTP response header syntax

    Use res.setHeader(name, value) to set headers correctly.
  2. Step 2: Check the correct header name and value type

    Header name is case-insensitive but usually 'ETag', and value must be a string.
  3. Final Answer:

    res.setHeader('ETag', '12345') -> Option A
  4. Quick Check:

    Set header with res.setHeader('ETag', value) [OK]
Hint: Use res.setHeader('ETag', 'value') to set ETag [OK]
Common Mistakes:
  • Using incorrect method names like res.header or res.set
  • Passing number instead of string as header value
  • Trying to assign ETag directly as a property
3. Consider this Node.js code snippet handling a request with an ETag check:
const etag = 'abc123';
if (req.headers['if-none-match'] === etag) {
  res.statusCode = 304;
  res.end();
} else {
  res.setHeader('ETag', etag);
  res.end('Hello World');
}

What will the server respond if the client sends header If-None-Match: abc123?
medium
A. Respond with status 200 and body 'Hello World'
B. Respond with status 500 Internal Server Error
C. Respond with status 304 and no body
D. Respond with status 404 Not Found

Solution

  1. Step 1: Check the condition comparing If-None-Match header

    The code compares req.headers['if-none-match'] to etag which is 'abc123'. If equal, it sets status 304.
  2. Step 2: Understand HTTP 304 meaning

    Status 304 means Not Modified, so no body is sent and client uses cached content.
  3. Final Answer:

    Respond with status 304 and no body -> Option C
  4. Quick Check:

    If-None-Match matches ETag = 304 no body [OK]
Hint: If-None-Match equals ETag means 304 Not Modified [OK]
Common Mistakes:
  • Thinking 304 responses include body content
  • Confusing 304 with 200 OK
  • Ignoring the If-None-Match header check
4. This Node.js code tries to handle ETag conditional requests but has a bug:
const etag = 'xyz789';
if (req.headers['If-None-Match'] === etag) {
  res.statusCode = 304;
  res.end();
} else {
  res.setHeader('etag', etag);
  res.end('Content');
}

What is the bug causing the ETag check to fail?
medium
A. ETag value should be a number, not a string
B. Header name case mismatch: 'If-None-Match' vs 'if-none-match'
C. res.end() is missing a callback function
D. res.statusCode must be set after res.end()

Solution

  1. Step 1: Check header name case sensitivity in Node.js

    Node.js lowercases all incoming header names, so req.headers['If-None-Match'] is undefined; correct is req.headers['if-none-match'].
  2. Step 2: Confirm impact on ETag comparison

    Because the header is undefined, the condition never matches, so 304 is never sent.
  3. Final Answer:

    Header name case mismatch: 'If-None-Match' vs 'if-none-match' -> Option B
  4. Quick Check:

    Headers lowercase in Node.js = use 'if-none-match' [OK]
Hint: Node.js headers are lowercase keys [OK]
Common Mistakes:
  • Using wrong case for header keys
  • Thinking ETag must be numeric
  • Misordering res.statusCode and res.end()
5. You want to optimize your Node.js server to use ETags and respond with 304 when content is unchanged. Which approach correctly combines generating an ETag and handling conditional requests?
hard
A. Generate a hash of the response body, set it as ETag header, then compare with req.headers['if-none-match'] to decide 304 or 200
B. Always send status 200 with ETag header, ignoring If-None-Match header
C. Set ETag header only on POST requests and ignore GET requests
D. Use res.setHeader('Cache-Control', 'no-store') to disable caching instead of ETags

Solution

  1. Step 1: Understand ETag generation

    ETags should uniquely represent the current content, often by hashing the response body.
  2. Step 2: Use conditional request header to decide response

    Compare req.headers['if-none-match'] with generated ETag; if equal, respond 304, else send content with new ETag.
  3. Final Answer:

    Generate a hash of the response body, set it as ETag header, then compare with req.headers['if-none-match'] to decide 304 or 200 -> Option A
  4. Quick Check:

    Hash body -> set ETag -> compare If-None-Match -> 304 or 200 [OK]
Hint: Hash content, set ETag, compare If-None-Match for 304 [OK]
Common Mistakes:
  • Ignoring If-None-Match header
  • Sending 200 always without checking ETag
  • Misusing Cache-Control to replace ETag logic
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard