You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx反向代理:如何根据响应内容特定词汇禁用缓存?

How to Disable Cache for Pages with Specific Content (No Backend Changes) in Nginx

Absolutely, you can pull this off without touching your backend code—Nginx has several flexible tools to inspect response content and adjust cache headers on the fly. Let’s break down the most practical approaches tailored to your needs:

The ngx_lua module (bundled with OpenResty) is the most efficient way to handle content-based logic in Nginx. Here's how to set it up:

Step 1: Ensure ngx_lua is installed

If you’re using OpenResty, this module is included by default. For standard Nginx, compile it with --add-module=path/to/ngx_lua during installation.

Step 2: Configure Nginx

Add this to your server or location block:

location / {
    proxy_pass http://your-backend-server;

    # Only process text/html responses to save resources
    set $no_cache 0;
    if ($content_type ~* text/html) {
        set $no_cache 1;
    }

    # Inspect response body and adjust cache headers
    body_filter_by_lua_block {
        local content_chunk = ngx.arg[1]
        local target_word = "your-specific-term"  # Replace with your target vocabulary

        # Check if the chunk contains the target word
        if string.find(content_chunk, target_word) then
            # Override headers to disable caching
            ngx.header["Cache-Control"] = "no-store, no-cache, must-revalidate"
            ngx.header["Pragma"] = "no-cache"
            ngx.header["Expires"] = "0"
        end
    }

    # Apply cache bypass rules
    proxy_cache_bypass $no_cache;
    proxy_no_cache $no_cache;
}

Notes:

  • For large responses, check only a portion of the content (e.g., first 10KB) to avoid high memory usage: string.find(string.sub(content_chunk, 1, 10240), target_word)
  • Use string.lower(content_chunk) if you need case-insensitive matching.

2. Using Embedded Perl

If you prefer Perl, Nginx’s ngx_http_perl_module can handle content inspection too.

Step 1: Enable the Perl module

Compile Nginx with --with-http_perl_module and ensure Perl is installed on your server.

Step 2: Configure Nginx

Add this to your config:

http {
    server {
        location / {
            proxy_pass http://your-backend-server;

            perl_body_filter 'sub {
                my ($r, $chunk, $eof) = @_;
                my $target_word = "your-specific-term";

                # Check for the target word in the response chunk
                if (index($chunk, $target_word) != -1) {
                    $r->header_out("Cache-Control", "no-store, no-cache, must-revalidate");
                    $r->header_out("Pragma", "no-cache");
                    $r->header_out("Expires", "0");
                }
                return $chunk;
            }';
        }
    }
}

Notes:

  • Perl filters are slightly slower than Lua for high-traffic sites, so monitor performance if you use this approach.
  • The $eof flag indicates the end of the response—you can use it to run final checks if needed.

3. Piping Response to a PHP Script

If you’re more comfortable with PHP, you can forward the backend response to a PHP script for processing, then send the modified response to the client.

Configure Nginx

location / {
    # Fetch backend response and store it temporarily
    proxy_pass http://your-backend-server;
    proxy_store on;
    proxy_store_access user:rw group:rw all:r;
    set $temp_response $request_filename;

    # Pass the temporary file to PHP for processing
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME /path/to/your/content-processor.php;
    fastcgi_param TEMP_RESPONSE_FILE $temp_response;
}

Example PHP Script (content-processor.php)

<?php
$temp_file = $_SERVER['TEMP_RESPONSE_FILE'];
$content = file_get_contents($temp_file);
$target_word = "your-specific-term";

// Check for the target word and adjust headers
if (strpos($content, $target_word) !== false) {
    header("Cache-Control: no-store, no-cache, must-revalidate");
    header("Pragma: no-cache");
    header("Expires: 0");
}

// Send the original content to the client
echo $content;
// Clean up the temporary file
unlink($temp_file);
?>

Notes:

  • This approach adds extra overhead due to file I/O and PHP processing, so it’s best suited for low-traffic environments.
  • Adjust the PHP-FPM socket path and script location to match your server setup.

4. Modifying Nginx Source Code

If you’re comfortable compiling Nginx from source, you can add custom logic directly into the proxy module.

Approach:

  1. Download the Nginx source code and navigate to src/http/modules (where ngx_http_proxy_module.c is located).
  2. Locate the function that processes backend response bodies—look for ngx_http_proxy_process_body or similar.
  3. Insert code to read response chunks, check for your target word, and modify cache headers if a match is found:
u_char *target_word = (u_char *)"your-specific-term";
size_t word_length = ngx_strlen(target_word);

// Check if the chunk contains the target word
if (ngx_strstr(chunk->data, target_word, word_length, chunk->len) != NULL) {
    // Add/override Cache-Control header
    ngx_table_elt_t *cache_control = ngx_list_push(&r->headers_out.headers);
    cache_control->hash = 1;
    ngx_str_set(&cache_control->key, "Cache-Control");
    ngx_str_set(&cache_control->value, "no-store, no-cache, must-revalidate");

    // Repeat for Pragma and Expires headers
    ngx_table_elt_t *pragma = ngx_list_push(&r->headers_out.headers);
    pragma->hash = 1;
    ngx_str_set(&pragma->key, "Pragma");
    ngx_str_set(&pragma->value, "no-cache");
}
  1. Recompile Nginx with your modified code and test thoroughly.

Notes:

  • This requires knowledge of C and Nginx’s internal API—only attempt this if you’re confident with low-level modifications.
  • Keep track of your changes so you can reapply them when updating Nginx.

内容的提问来源于stack exchange,提问作者POMATu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:34:21