Operations 12 min read

Configuring Nginx for High‑Performance Static Websites: Caching, Gzip, CORS, and Anti‑Hotlinking

This article explains how to configure Nginx to serve static sites efficiently by setting up proper caching rules, enabling Gzip compression, handling cross‑origin resource sharing and anti‑hotlinking, while also providing sample configuration snippets and a brief note on related promotional offers.

Top Architect
Top Architect
Top Architect
Configuring Nginx for High‑Performance Static Websites: Caching, Gzip, CORS, and Anti‑Hotlinking

Overview

This blog post summarizes four key Nginx configuration topics—caching, Gzip compression, cross‑origin resource sharing (CORS), and anti‑hotlinking—based on practical production experience, aiming to help readers improve performance and security of static websites.

Cache

By configuring an appropriate cache strategy, browsers can reuse previously fetched resources without repeatedly contacting the server, reducing latency and improving user experience.

Cache control can be set using either a positive or negative Expires header value, which determines the Cache-Control directive: a negative value means no-cache , while a non‑negative value (including zero) means max-age=time .

location ~* \.(jpg|jpeg|png|gif)$ {
    expires 30d;
}
# expires 30s;   # cache for 30 seconds
# expires 30m;   # cache for 30 minutes
# expires 2h;    # cache for 2 hours
# expires 30d;   # cache for 30 days

Principle Analysis

Process and steps:

1. The user’s first request reaches the server; no cached copy exists, so the browser sends a request.

2. The server returns a 200 response with the resource and appropriate cache headers.

3. On subsequent requests, the browser checks its local cache for a matching file.

4. If no cached file is found, step 2 is repeated.

5. If a cached file exists, its expiration is evaluated using the Expires header.

6. If the cached file has not expired, the browser serves the data directly from the cache.

7. If the Expires header indicates expiration, the browser checks whether the file has changed using ETag or Last-Modified .

8. If the file has not changed, the server returns a 304 status and the browser uses the cached copy.

9. If the file has changed, the browser fetches the new data and stores it according to the server’s cache‑control policy.

Cache Header Explanation

Browsers perform two types of caching: strong (forced) caching and negotiated caching . Forced caching relies on the Expires and Cache-Control response headers. Cache-Control has higher priority than Expires . In HTTP/1.0, Expires was used, but it is vulnerable to client‑server time mismatches, so HTTP/1.1 prefers Cache-Control .

Gzip Module

Enabling gzip compression reduces the amount of data transferred over HTTP, speeding up page load times.

location ~ .*\.(jpg|gif|png|js)$ {
    gzip on;
    gzip_http_version 1.1;
    gzip_comp_level 2; # compression level, 1‑9
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif img/png;
}

CORS and Anti‑Hotlinking

These settings improve security by allowing only authorized domains to access resources.

server {
    listen 80;
    server_name www.stark.com;

    location / {
        # Allow any origin (*) or specify trusted domains
        add_header 'Access-Control-Allow-Origin' 'http://stark1.com https://stark2.com';
        # Allowed methods
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        # Allowed request headers
        add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type';
        # Max age for pre‑flight request caching
        add_header 'Access-Control-Max-Age' 1728000;

        # Handle pre‑flight OPTIONS request
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }
        # Other server configuration goes here
    }
}

Anti‑hotlinking checks the Referer header to prevent other sites from using your static resources, saving bandwidth.

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        root /path/to/your/files;
        valid_referers none blocked server_names *.yourdomain.com;
        if ($invalid_referer) {
            return 403;
        }
    }
}

Promotional Note

The author also promotes a ChatGPT‑focused community offering paid memberships, exclusive accounts, tutorials, and other benefits, encouraging readers to join for additional AI‑related resources.

CachingCORSNginxGzipServer Configurationanti-hotlinking
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.