Come faccio ad aggiungere intestazioni senza cache a tutte le 404 pagine servite da apache e nginx?


9

Di recente ho riscontrato un problema dopo essere passato a Cloudflare e la soluzione è sostanzialmente quella di impedire a Cloudflare di memorizzare nella cache 404 risposte.

Nella nostra configurazione multi-server con bilanciamento del carico, si verificano 404 occasionali, ma vengono rapidamente risolti da rsync (tramite lsyncd). Prima di Cloudflare, una nuova richiesta al file 404 sarebbe diventata molto rapidamente 200 poiché rsync faceva il suo lavoro.

Tuttavia, poiché Cloudflare memorizza nella cache tutti i dati basati sull'intestazione della cache e né apache né nginx inviano un'intestazione senza cache per 404 secondi, Cloudflare finisce per memorizzare nella cache la risposta 404 per un po '.

Ho cercato una soluzione per aggiungere globalmente un'intestazione simile per 404s sia in apache che in nginx (globalmente, per tutti i domini ospitati), ma finora sono rimasti vuoti.

Qualcuno può aiutare?

Grazie.


Domanda simile, anche se solo per Apache (ancora senza risposta): serverfault.com/questions/331544/… .
Artem Russakovskii,

Finora, sono abbastanza sicuro che non puoi ignorare le intestazioni restituite dai gestori 404 predefiniti sia in apache che in nginx (per favore, dimostrami che mi sbaglio!). Sono stato in grado di sovrascrivere il gestore 404 e puntarlo a un file PHP che invia tali intestazioni in apache, ma poiché nginx non ha il supporto PHP sulla mia configurazione e l'impostazione "scade -1;" sulla posizione 404 non sembrava davvero fare nulla, sono ancora in perdita su come farlo in nginx.
Artem Russakovskii,

Risposte:


6

Non riesci a cavartela usando una direttiva error_page e poi gestisci la posizione separatamente con l'intestazione aggiunta?

ad es. in Nginx:

    server {
      ...
      error_page 404 /404.html;
      location = /404.html {
        root   /usr/share/nginx/html;
        add_header Cache-Control "no-cache" always;
      }
    }

1
Ci sono due problemi qui, ma questa è la direzione in cui sono andato. 1. Non volevo ignorare la pagina 404 predefinita e dovevo creare regole in ogni listenpoiché locationnon è supportato httpdirettamente all'interno . 2. Ancora più importante, il tuo frammento in realtà non funziona perché add_header si applica solo a 20X e 30X ( nginx.org/en/docs/http/ngx_http_headers_module.html ). Tuttavia, siamo fortunati, poiché a partire dalla recente 1.7.5, è ora possibile aggiungere un alwaysmodificatore che lo applicherà a tutti i codici di risposta. Ho dovuto aggiornare nginx ma è stato un bel calcio nel culo. Funziona.
Artem Russakovskii,

2
Ho aggiornato la mia risposta, dovresti forse aggiungere una risposta che mostri cosa hai fatto per risolvere la domanda?
Jimmiw,

Sembra omettere anche le rootopere. Se viene rimosso, è praticamente quello che ho finito per fare nginx.
Artem Russakovskii,

Per apache, ho deciso di voler effettivamente utilizzare una pagina personalizzata, quindi ho fatto questo: ErrorDocument 404 /path/to/my/404.php. E poi all'interno del 404.php, ho fatto <? Php // non memorizzare nella cache l'intestazione 404 ("Cache-Control: no-cache, must-revalidate"); // header HTTP / 1.1 ("Scadenza: sabato 26 luglio 1997 05:00:00 GMT"); // Data del passato?>
Artem Russakovskii,

Segnerò la tua risposta come accettata. Se qualcuno vuole fornire una risposta apache più generica in seguito, o una nginx che serverfunzioni a livello globale anziché per , può ottenere il voto.
Artem Russakovskii,

5

Puoi farlo anche in questo modo:

map $status $cache_header {
    default <for_other_codes>;
    404     "no-cache";
}


server {

    [ ... ]

    add_header "Cache-Control" $cache_header always;

}

Intelligente. Probabilmente andrò con l'altra soluzione, dal momento che funziona già e non richiede di specificare un'intestazione Cache-Control predefinita ogni volta, ma questo era un pensiero fuori dagli schemi.
Artem Russakovskii,

Manca un punto e virgola dopo, 404 "no-cache"ma la stupida restrizione di modifica di minimo 6 caratteri di stackexchange mi impedisce di risolverlo. Chiaramente non è una buona restrizione per un sito che riguarda la codifica e le configurazioni ...
nh2

3

In apache 2.4, potresti provare qualcosa del tipo:

FileETag None
<IfModule mod_headers.c>
    Header always unset ETag "expr=%{REQUEST_STATUS} == 404"
    Header always set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" "expr=%{REQUEST_STATUS} == 404"
    Header always set Pragma "no-cache" "expr=%{REQUEST_STATUS} == 404"
    Header always set Expires "Wed, 11 Jan 1984 05:00:00 GMT" "expr=%{REQUEST_STATUS} == 404"
</IfModule>

L' alwaysè importante perché si tratta di una:

Stai aggiungendo un'intestazione a una risposta non riuscita (non 2xx) generata localmente, come un reindirizzamento, nel qual caso nella risposta finale viene utilizzata solo la tabella corrispondente a sempre.

Hai detto tutti i 404, ma per un riferimento completo, ovviamente, potrebbe avere senso avvolgerlo in uno <FilesMatch>o <LocationMatch>limitare l'ambito.

Credo che questa sia una nuova funzionalità di Apache 2.4 poiché l'uso dei exprcondizionali non è nella versione 2.2 della documentazione mod_headers.

curl -I [foo] prova senza questa configurazione:

HTTP/1.1 404 Not Found
Date: Thu, 24 May 2018 17:44:29 GMT
Server: Apache/2.4.18 (Ubuntu)
Content-Type: text/html; charset=iso-8859-1

curl -I [foo] prova con questa configurazione:

HTTP/1.1 404 Not Found
Date: Thu, 24 May 2018 17:44:42 GMT
Server: Apache/2.4.18 (Ubuntu)
Cache-Control: max-age=0, no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Content-Type: text/html; charset=iso-8859-1

fonti:

http://httpd.apache.org/docs/current/mod/mod_headers.html


0

i miei cinque centesimi sulla questione -

nel nostro progetto PHP abbiamo poche 404 pagine, quindi decido di farlo a livello di PHP usando le funzioni header () di PHP

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.