DevToolBoxFREE
Blog

HTTP Headers Complete Guide: Request, Response & Security Headers

12 min readby DevToolBox

HTTP headers are the invisible backbone of the web. Every request and response you make carries a set of headers that control caching, authentication, content negotiation, security policies, and much more. This complete guide covers the most important request headers, response headers, security headers, and CORS configuration for developers in 2026.

Essential Request Headers

Request headers are sent by the client (browser or API consumer) to the server. They carry metadata about the request, the client capabilities, and the desired response format.

// Common HTTP Request Headers

GET /api/users HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Accept: application/json
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Cache-Control: no-cache
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d"
If-Modified-Since: Thu, 01 Jan 2026 00:00:00 GMT
Origin: https://myapp.com
Referer: https://myapp.com/dashboard
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000

// Setting headers with fetch API
const response = await fetch('https://api.example.com/users', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Accept': 'application/json',
    'X-Request-ID': crypto.randomUUID(),
  },
});

HTTP Security Headers

Security headers protect your users from a wide range of attacks including XSS, clickjacking, and man-in-the-middle attacks. Every production web application should implement these headers.

// Essential Security Headers for Express.js
import express from 'express';

const app = express();

app.use((req, res, next) => {
  // Prevent XSS attacks
  res.setHeader('X-XSS-Protection', '1; mode=block');

  // Prevent MIME type sniffing
  res.setHeader('X-Content-Type-Options', 'nosniff');

  // Prevent clickjacking
  res.setHeader('X-Frame-Options', 'DENY');

  // Force HTTPS for 1 year (include subdomains)
  res.setHeader(
    'Strict-Transport-Security',
    'max-age=31536000; includeSubDomains; preload'
  );

  // Content Security Policy
  res.setHeader(
    'Content-Security-Policy',
    [
      "default-src 'self'",
      "script-src 'self' 'nonce-{RANDOM}' https://cdn.example.com",
      "style-src 'self' 'unsafe-inline'",
      "img-src 'self' data: https:",
      "font-src 'self'",
      "connect-src 'self' https://api.example.com",
      "frame-ancestors 'none'",
    ].join('; ')
  );

  // Control referrer information
  res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');

  // Control browser features
  res.setHeader(
    'Permissions-Policy',
    'camera=(), microphone=(), geolocation=(self)'
  );

  next();
});

CORS: Cross-Origin Resource Sharing

CORS allows servers to specify which origins are permitted to access their resources. It is enforced by browsers but not by server-to-server requests or tools like curl.

// CORS Configuration — Express.js

import cors from 'cors';

// Simple CORS for public API
app.use(cors({
  origin: '*',
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
}));

// Strict CORS for production
const allowedOrigins = [
  'https://myapp.com',
  'https://www.myapp.com',
  process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : null,
].filter(Boolean);

app.use(cors({
  origin: (origin, callback) => {
    // Allow requests with no origin (mobile apps, curl, etc.)
    if (!origin) return callback(null, true);

    if (allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error(`CORS: Origin ${origin} not allowed`));
    }
  },
  methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-ID'],
  exposedHeaders: ['X-Total-Count', 'X-RateLimit-Remaining'],
  credentials: true,       // Allow cookies
  maxAge: 86400,           // Cache preflight for 24 hours
}));

// Manual preflight handling
app.options('*', cors()); // Enable pre-flight across all routes

Caching Headers

Correct caching headers dramatically improve performance by letting browsers and CDNs reuse responses without making new requests to the origin server.

// HTTP Caching Headers

// 1. Cache-Control directives
Cache-Control: no-store          // Never cache (sensitive data)
Cache-Control: no-cache          // Revalidate before using cache
Cache-Control: private           // Browser cache only (not CDN)
Cache-Control: public, max-age=31536000  // Cache for 1 year (immutable assets)
Cache-Control: public, max-age=3600, stale-while-revalidate=60

// 2. ETag for conditional requests (server generates a hash of the content)
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d"
// Client sends back on subsequent requests:
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d"
// Server responds 304 Not Modified if unchanged

// 3. Last-Modified
Last-Modified: Thu, 23 Feb 2026 10:00:00 GMT
If-Modified-Since: Thu, 23 Feb 2026 10:00:00 GMT

// Setting cache headers in Next.js
export async function GET() {
  return new Response(JSON.stringify(data), {
    headers: {
      'Content-Type': 'application/json',
      'Cache-Control': 'public, max-age=3600, stale-while-revalidate=60',
      'ETag': `"${hash(data)}"`,
    },
  });
}

// Strategy by asset type:
// HTML pages:     Cache-Control: no-cache (always revalidate)
// CSS/JS bundles: Cache-Control: public, max-age=31536000, immutable
// API responses:  Cache-Control: private, no-cache
// Images:         Cache-Control: public, max-age=86400

Frequently Asked Questions

What is the difference between Authorization and Authentication headers?

HTTP does not have a dedicated Authentication header. Authentication credentials are sent via the Authorization header (e.g., Bearer tokens, Basic auth). The WWW-Authenticate response header tells the client what authentication scheme to use.

Why does my CORS preflight fail?

CORS preflight OPTIONS requests fail when the server does not return the correct Access-Control-Allow-Origin, Access-Control-Allow-Methods, or Access-Control-Allow-Headers response headers. Ensure your server explicitly handles OPTIONS requests and returns these headers.

What is the Content-Security-Policy header?

CSP (Content-Security-Policy) is a powerful security header that tells browsers which content sources are trusted. It prevents XSS attacks by blocking inline scripts and restricting resource loading to approved domains.

How do I force HTTPS with HTTP headers?

Use the Strict-Transport-Security (HSTS) header: Strict-Transport-Security: max-age=31536000; includeSubDomains. Once received, browsers will only connect via HTTPS for the specified max-age duration.

Related Tools

𝕏 Twitterin LinkedIn
Was this helpful?

Stay Updated

Get weekly dev tips and new tool announcements.

No spam. Unsubscribe anytime.

Try These Related Tools

🔓CORS Tester

Related Articles

REST API Design Guide: Best Practices for 2026

Design robust REST APIs with this comprehensive guide: resource naming, HTTP methods, pagination, filtering, error handling, versioning, authentication, caching, HATEOAS, and OpenAPI documentation.

JWT Authentication: Complete Implementation Guide

Implement JWT authentication from scratch. Token structure, access and refresh tokens, Node.js implementation, client-side management, security best practices, and Next.js middleware.

How to Fix CORS Errors: The Complete Troubleshooting Guide

Fix CORS errors step by step. Covers Access-Control-Allow-Origin, preflight requests, credentials, and server configs for Express, Django, Nginx, and more.