NetTool1

HTTP Headers Explained: Request, Response & Security Headers

· 12 min read

HTTP headers are the unsung heroes of web communication. Every time you load a webpage, stream a video, or submit a form, dozens of headers work behind the scenes to make it happen. They carry critical metadata about requests and responses, control caching behavior, enforce security policies, and enable modern web features.

Understanding HTTP headers isn't just for backend developers anymore. Frontend engineers need them for API integration, DevOps teams rely on them for performance optimization, and security professionals use them to protect applications from attacks. This guide breaks down everything you need to know about HTTP headers, from basic concepts to advanced security implementations.

Table of Contents

What Are HTTP Headers?

HTTP headers are key-value pairs sent between clients and servers during HTTP communication. They provide essential context about the request or response, including content type, encoding, authentication credentials, caching directives, and security policies.

Headers follow a simple format: Header-Name: value. Each header appears on its own line, and a blank line separates headers from the message body. While HTTP/1.1 uses plain text headers, HTTP/2 and HTTP/3 compress them using HPACK and QPACK algorithms respectively.

Headers fall into four main categories:

Modern web applications typically exchange 20-40 headers per request-response cycle. Some are mandatory (like Host in HTTP/1.1), while others are optional but highly recommended for security and performance.

Pro tip: Use your browser's DevTools Network tab to inspect headers in real-time. This is invaluable for debugging API issues and understanding how third-party services communicate with your application.

Request Headers: What Browsers Send

Request headers tell the server what the client wants and what it can handle. They include information about accepted content types, preferred languages, authentication credentials, and the client's capabilities.

Here are the most important request headers you'll encounter:

Header Purpose Example
Host Specifies the domain name of the server Host: example.com
User-Agent Identifies the client software User-Agent: Mozilla/5.0...
Accept Media types the client can process Accept: application/json
Accept-Language Preferred languages for the response Accept-Language: en-US,en;q=0.9
Accept-Encoding Compression algorithms supported Accept-Encoding: gzip, br
Authorization Authentication credentials Authorization: Bearer token123
Cookie Stored cookies for the domain Cookie: session=abc123
Referer URL of the previous page Referer: https://google.com

Understanding the Accept Header

The Accept header uses quality values (q-values) to indicate preference when multiple formats are acceptable. Values range from 0 to 1, with 1 being the highest priority:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

This tells the server: "I prefer HTML or XHTML, but I'll accept XML with 90% preference, and anything else with 80% preference." Servers use this to perform content negotiation and return the most appropriate format.

The User-Agent Header

The User-Agent header identifies the client software, operating system, and device type. While useful for analytics and serving device-specific content, it's also notoriously unreliable due to user-agent spoofing.

Modern best practice is to use feature detection instead of user-agent sniffing. However, the header remains valuable for logging, debugging, and detecting bots.

Quick tip: Test your API endpoints with different User-Agent strings to ensure they don't break for legitimate clients. Some servers incorrectly block requests with unfamiliar user agents.

Response Headers: What Servers Return

Response headers provide metadata about the server's response, including content type, caching instructions, security policies, and server information. They're crucial for proper content rendering, performance optimization, and security.

Key response headers include:

Header Purpose Example
Content-Type Media type of the response body Content-Type: text/html; charset=utf-8
Content-Length Size of the response body in bytes Content-Length: 1234
Content-Encoding Compression algorithm used Content-Encoding: gzip
Set-Cookie Sends cookies to the client Set-Cookie: id=a3; Secure; HttpOnly
Location URL for redirects Location: https://example.com/new
Server Information about the server software Server: nginx/1.18.0
Date Date and time the response was sent Date: Mon, 31 Mar 2026 12:00:00 GMT
ETag Unique identifier for resource version ETag: "33a64df551425fcc55e"

Content-Type and Character Encoding

The Content-Type header is critical for proper content rendering. It tells the browser how to interpret the response body. Always include the character encoding (usually UTF-8) to prevent encoding issues:

Content-Type: application/json; charset=utf-8
Content-Type: text/html; charset=utf-8
Content-Type: image/png

Missing or incorrect Content-Type headers cause browsers to guess the content type (MIME sniffing), which can lead to security vulnerabilities and rendering issues.

The Set-Cookie Header

The Set-Cookie header creates cookies on the client side. Modern cookies should always include security attributes:

Set-Cookie: sessionId=abc123; Secure; HttpOnly; SameSite=Strict; Max-Age=3600

Security Headers: Protecting Your Application

Security headers are your first line of defense against common web vulnerabilities. They instruct browsers to enforce security policies that protect users from attacks like XSS, clickjacking, and man-in-the-middle attacks.

Every production application should implement these essential security headers:

Content-Security-Policy (CSP)

CSP prevents XSS attacks by controlling which resources the browser can load. It's one of the most powerful security headers but requires careful configuration:

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com

Start with a restrictive policy and gradually relax it as needed. Use Content-Security-Policy-Report-Only to test policies without breaking your site.

Strict-Transport-Security (HSTS)

HSTS forces browsers to use HTTPS for all future requests to your domain, preventing protocol downgrade attacks:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

The preload directive allows you to submit your domain to the HSTS preload list, which is hardcoded into browsers. This provides protection even on the first visit.

X-Frame-Options

This header prevents clickjacking attacks by controlling whether your site can be embedded in frames:

X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN

Use DENY to prevent all framing, or SAMEORIGIN to allow framing only from your own domain. The newer frame-ancestors CSP directive provides more granular control.

X-Content-Type-Options

This simple header prevents MIME sniffing attacks by forcing browsers to respect the declared Content-Type:

X-Content-Type-Options: nosniff

Always include this header. It's a one-line addition that prevents a whole class of vulnerabilities.

Referrer-Policy

Control how much referrer information is sent with requests:

Referrer-Policy: strict-origin-when-cross-origin

This policy sends the full URL for same-origin requests but only the origin for cross-origin requests, balancing privacy and functionality.

Permissions-Policy

The modern replacement for Feature-Policy, this header controls which browser features your site can use:

Permissions-Policy: geolocation=(), microphone=(), camera=()

Disable features you don't use to reduce your attack surface and improve privacy.

Pro tip: Use the Security Headers Checker tool to analyze your site's security headers and get specific recommendations for improvement.

Caching Headers: Performance Optimization

Caching headers dramatically improve performance by allowing browsers and CDNs to store and reuse responses. Proper caching reduces server load, decreases bandwidth usage, and speeds up page loads for users.

Cache-Control

The Cache-Control header is the primary mechanism for controlling caching behavior. It supports multiple directives that can be combined:

Cache-Control: public, max-age=31536000, immutable
Cache-Control: private, no-cache, no-store, must-revalidate
Cache-Control: public, max-age=3600, stale-while-revalidate=86400

Common directives include:

ETag and Conditional Requests

ETags enable efficient cache validation. The server sends an ETag (entity tag) with the response, and the client includes it in subsequent requests:

// Initial response
ETag: "33a64df551425fcc55e"

// Subsequent request
If-None-Match: "33a64df551425fcc55e"

// Server response if unchanged
304 Not Modified

This saves bandwidth by avoiding full response bodies when content hasn't changed. The server returns a 304 status code, and the browser uses its cached version.

Caching Strategy by Content Type

Different content types require different caching strategies:

Quick tip: Use the HTTP Headers Analyzer to inspect caching headers and identify optimization opportunities in your application.

CORS Headers: Cross-Origin Resource Sharing

CORS headers control how browsers handle cross-origin requests. By default, browsers block JavaScript from making requests to different origins for security reasons. CORS headers explicitly allow specific cross-origin interactions.

Access-Control-Allow-Origin

This header specifies which origins can access the resource:

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Origin: *

Use specific origins for APIs that require authentication. The wildcard (*) allows any origin but cannot be used with credentials.

Access-Control-Allow-Methods

Specifies which HTTP methods are allowed for cross-origin requests:

Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS

Access-Control-Allow-Headers

Lists which headers can be used in the actual request:

Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With

Access-Control-Allow-Credentials

Indicates whether the response can be exposed when credentials are included:

Access-Control-Allow-Credentials: true

When this is set to true, Access-Control-Allow-Origin cannot be * - it must be a specific origin.

Preflight Requests

For certain requests (like those with custom headers or non-simple methods), browsers send a preflight OPTIONS request first. Your server must respond with appropriate CORS headers:

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

The Access-Control-Max-Age header tells the browser how long to cache the preflight response, reducing unnecessary OPTIONS requests.

Custom Headers: When and How to Use Them

Custom headers let you pass application-specific metadata between clients and servers. While HTTP provides many standard headers, sometimes you need to communicate information that doesn't fit existing headers.

Naming Conventions

Custom headers traditionally used the X- prefix (like X-Custom-Header), but RFC 6648 deprecated this practice. Modern custom headers should use descriptive names without the prefix:

API-Key: your-api-key-here
Request-ID: 550e8400-e29b-41d4-a716-446655440000
Client-Version: 2.1.0

Common Use Cases

Custom headers are useful for:

Best Practices

When implementing custom headers:

  1. Document them thoroughly in your API documentation
  2. Use consistent naming across your application
  3. Validate header values on the server side
  4. Consider security implications (don't expose sensitive data)
  5. Remember that headers increase request size
  6. Configure CORS properly if used in cross-origin requests

Pro tip: Avoid putting large amounts of data in headers. Headers are meant for metadata, not payload data. If you need to send substantial information, use the request or response body instead.

Debugging HTTP Headers

Debugging header issues is a common task for web developers. Headers can cause mysterious bugs when misconfigured, from broken authentication to caching problems to CORS errors.

Browser DevTools

Every modern browser includes developer tools with a Network tab that displays all headers for each request and response. To inspect headers:

  1. Open DevTools (F12 or Cmd+Option+I)
  2. Navigate to the Network tab
  3. Reload the page or trigger the request
  4. Click on a request to see detailed header information

The Network tab shows both request and response headers, timing information, and the full request/response cycle.

Command Line Tools

For server-side debugging or automated testing, command-line tools are invaluable:

# View all headers with curl
curl -I https://example.com

# View headers with verbose output
curl -v https://example.com

# Send custom headers
curl -H "