Apache와 nginx가 제공하는 모든 404 페이지에 캐시없는 헤더를 추가하려면 어떻게합니까?


9

최근 Cloudflare로 전환 한 후 문제가 발생했으며 해결책은 기본적으로 Cloudflare가 404 응답을 캐싱하지 못하게하는 것입니다.

로드 밸런싱 된 다중 서버 설정에서 가끔 404가 발생하지만 rsync (lsyncd를 통해)로 빠르게 수정됩니다. Cloudflare 이전에는 rsync가 작업을 수행함에 따라 404ed 파일에 대한 재 요청이 매우 빠르게 200이되었습니다.

그러나 Cloudflare는 캐싱 헤더를 기반으로 모든 데이터를 캐시하고, 아파치 나 nginx는 404에 대해 비 캐시 헤더를 보내지 않으므로 Cloudflare는 404 응답을 잠시 동안 캐싱합니다.

아파치와 nginx (전 세계적으로 모든 호스트 된 도메인)에서 404에 대한 이러한 헤더를 전 세계적으로 추가하는 솔루션을 찾고 있었지만 지금까지는 비어 있습니다.

누구든지 도울 수 있습니까?

감사합니다.


비슷한 질문이지만 아파치 (아직도 대답하지 않음) : serverfault.com/questions/331544/… .
Artem Russakovskii

지금까지 아파치와 nginx에서 기본 404 핸들러가 반환 한 헤더를 재정의 할 수 없다고 확신합니다 (나를 잘못 증명하십시오!). 404 핸들러를 무시하고 아파치에서 그러한 헤더를 보내는 PHP 파일을 가리킬 수 있었지만 nginx는 설정에서 PHP를 지원하지 않고 "expires -1;" 404 위치에서 실제로 아무것도하지 않는 것처럼 보였지만 nginx 에서이 작업을 수행하는 방법에 대해서는 여전히 잃어 버렸습니다.
Artem Russakovskii 7:07에

답변:


6

error_page 지시문을 사용하여 얻을 수 없으며 추가 된 헤더로 위치를 개별적으로 처리 할 수 ​​있습니까?

예를 들어 Nginx에서 :

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

1
여기에는 두 가지 문제가 있지만 이것이 제가 진행 한 방향입니다. 1. 나는 기본 404 페이지를 무시하고 모든 경우에 규칙을 만들어야하고 싶지 않았다 listen때문에 location내부 지원되지 않습니다 http직접. 2. 더 중요한 것은 add_header가 20X 및 30X ( nginx.org/en/docs/http/ngx_http_headers_module.html ) 에만 적용되므로 스 니펫은 실제로 작동하지 않습니다 . 그러나 최근 출시 된 1.7.5 always부터 모든 응답 코드에 적용 할 수정자를 추가 할 수 있습니다 . 나는 nginx를 업그레이드해야했지만 엉덩이에서 좋은 킥이었다. 효과가있다.
Artem Russakovskii

2
답변을 업데이트했습니다. 질문을 해결하기 위해 무엇을했는지 보여주는 답변을 추가해야합니까?
jimmiw

생략 root해도 효과가 있습니다. 그것이 제거되면, 그것은 결국 nginx를 위해했던 일입니다.
Artem Russakovskii

아파치의 경우 실제로 사용자 정의 페이지를 사용하기로 결정했기 때문에 ErrorDocument 404 /path/to/my/404.php를 수행했습니다. 그런 다음 404.php에서 <? php // 404 헤더를 캐시하지 않습니다 ( "Cache-Control : no-cache, must-revalidate"); // HTTP / 1.1 헤더 ( "만료 : 토요일, 1997 년 7 월 26 일 05:00:00 GMT"); // 과거의 날짜?>
Artem Russakovskii

귀하의 답변을 수락 된 것으로 표시하고 있습니다. 누군가가 더 일반적인 아파치 답변을 나중에 제공하거나 n이 아닌 전 세계에서 작동하는 nginx 답변을 제공하려는 경우 사람들은 server불쾌감을 줄 수 있습니다.
Artem Russakovskii

5

이 방법으로도 할 수 있습니다.

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


server {

    [ ... ]

    add_header "Cache-Control" $cache_header always;

}

영리한. 이미 작동하고 매번 기본 Cache-Control 헤더를 지정할 필요가 없기 때문에 다른 솔루션과 함께 갈 것입니다. 그러나 이것은 상자 밖에서 생각했습니다.
Artem Russakovskii 19:01에

세미콜론이 누락 404 "no-cache"되었지만 stackexchange의 어리석은 최소 6 문자 편집 제한으로 인해 수정되지 않습니다. 코딩과 설정에 관한 모든 사이트에 대한 좋은 제한은 분명하지 않습니다.
nh2

3

아파치 2.4에서는 다음과 같은 것을 시도 할 수 있습니다.

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>

always이것이이기 때문에 중요하다 :

리디렉션과 같이 로컬로 생성 된 성공하지 않은 (2xx가 아닌) 응답에 헤더를 추가하는 경우 항상 해당하는 테이블 만 최종 응답에 사용됩니다.

당신은 모든 404을 말했지만, 물론 전체 참조는 의미가에 그것을 포장 할 수 <FilesMatch>또는 <LocationMatch>범위를 제한 할 수 있습니다.

expr조건부 를 사용 하는 것이 mod_headers 문서의 2.2 버전이 아니기 때문에 이것이 아파치 2.4의 새로운 기능이라고 생각합니다 .

curl -I [foo] 이 구성없이 테스트하십시오.

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] 이 구성으로 테스트하십시오.

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

출처 :

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


0

문제에 대한 나의 5 센트-

PHP 프로젝트에는 404 페이지가 거의 없으므로 PHP header () 함수를 사용하여 PHP 수준에서 수행하기로 결정했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.