ASP.NET Core의 응답 캐싱 미들웨어Response Caching Middleware in ASP.NET Core

작성자: Luke LathamJohn LuoBy Luke Latham and John Luo

예제 코드 살펴보기 및 다운로드 (다운로드 방법).View or download sample code (how to download).

이 문서에서는 ASP.NET Core 응용 프로그램에서 응답 캐싱 미들웨어를 구성하는 방법을 알아봅니다.This article explains how to configure Response Caching Middleware in an ASP.NET Core app. 미들웨어는 응답을 캐싱할 수 있는 시점을 결정하고 응답을 저장하고 캐시에서 가져온 응답을 제공합니다.The middleware determines when responses are cacheable, stores responses, and serves responses from cache. HTTP 캐싱 및 ResponseCache 특성에 대한 소개는 응답 캐싱을 참고하시기 바랍니다.For an introduction to HTTP caching and the ResponseCache attribute, see Response Caching.

패키지Package

참조를 Microsoft.AspNetCore.App 메타 패키지 에 대 한 패키지 참조를 추가 하거나 합니다 Microsoft.AspNetCore.ResponseCaching 패키지 합니다.Reference the Microsoft.AspNetCore.App metapackage or add a package reference to the Microsoft.AspNetCore.ResponseCaching package.

참조를 Microsoft.AspNetCore.All 메타 패키지 에 대 한 패키지 참조를 추가 하거나 합니다 Microsoft.AspNetCore.ResponseCaching 패키지 합니다.Reference the Microsoft.AspNetCore.All metapackage or add a package reference to the Microsoft.AspNetCore.ResponseCaching package.

패키지 참조를 추가 합니다 Microsoft.AspNetCore.ResponseCaching 패키지 있습니다.Add a package reference to the Microsoft.AspNetCore.ResponseCaching package.

구성Configuration

Startup.ConfigureServices에서 서비스 컬렉션에 미들웨어를 추가합니다.In Startup.ConfigureServices, add the middleware to the service collection.

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddResponseCaching();
    services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

그리고 미들웨어를 요청 처리 파이프라인에 추가하는 UseResponseCaching 확장 메서드를 이용해서 응용 프로그램이 미들웨어를 사용하도록 구성합니다.Configure the app to use the middleware with the UseResponseCaching extension method, which adds the middleware to the request processing pipeline. 예제 응용 프로그램은 최대 10초 동안 캐시가 응답을 캐싱할 수 있도록 Cache-Control 헤더를 응답에 추가합니다.The sample app adds a Cache-Control header to the response that caches cacheable responses for up to 10 seconds. 또한 Vary 헤더를 전송해서 후속 요청의 Accept-Encoding 헤더가 원본 요청과 일치하는 경우에만 캐시된 응답을 제공하도록 미들웨어를 구성합니다.The sample sends a Vary header to configure the middleware to serve a cached response only if the Accept-Encoding header of subsequent requests matches that of the original request. 다음 예제 코드에서 CacheControlHeaderValueHeaderNames를 사용하려면 Microsoft.Net.Http.Headers 네임스페이스에 대한 using 문이 필요합니다.In the code example that follows, CacheControlHeaderValue and HeaderNames require a using statement for the Microsoft.Net.Http.Headers namespace.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseResponseCaching();

    app.Use(async (context, next) =>
    {
        // For GetTypedHeaders, add: using Microsoft.AspNetCore.Http;
        context.Response.GetTypedHeaders().CacheControl = 
            new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(10)
            };
        context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] = 
            new string[] { "Accept-Encoding" };

        await next();
    });

    app.UseMvc();
}

응답 캐싱 미들웨어는 상태 코드가 200(정상)인 서버 응답만 캐시합니다.Response Caching Middleware only caches server responses that result in a 200 (OK) status code. 오류 페이지를 비롯한 다른 모든 응답은 미들웨어에 의해 무시됩니다.Any other responses, including error pages, are ignored by the middleware.

경고

인증된 클라이언트에 대한 콘텐츠를 포함하고 있는 응답은 미들웨어가 해당 응답을 저장하거나 제공하는 것을 막을 수 있도록 반드시 캐시가 불가능한 것으로 표시해야 합니다.Responses containing content for authenticated clients must be marked as not cacheable to prevent the middleware from storing and serving those responses. 미들웨어가 캐싱할 수 있는 응답인지 여부를 판단하는 방법에 대한 자세한 내용은 캐싱 조건을 참고하시기 바랍니다.See Conditions for caching for details on how the middleware determines if a response is cacheable.

옵션Options

미들웨어는 응답 캐싱을 제어하기 위한 세 가지 옵션을 제공합니다.The middleware offers three options for controlling response caching.

옵션Option 설명Description
UseCaseSensitivePathsUseCaseSensitivePaths 경로의 대/소문자를 구분해서 응답을 캐시할지 결정합니다.Determines if responses are cached on case-sensitive paths. 기본값은 false입니다.The default value is false.
MaximumBodySizeMaximumBodySize 캐시 가능한 응답 본문의 최대 바이트 크기입니다.The largest cacheable size for the response body in bytes. 기본값은 64 * 1024 * 1024(64MB)입니다.The default value is 64 * 1024 * 1024 (64 MB).
SizeLimitSizeLimit 응답 캐싱 미들웨어의 바이트 크기 제한입니다.The size limit for the response cache middleware in bytes. 기본값은 100 * 1024 * 1024(100MB)입니다.The default value is 100 * 1024 * 1024 (100 MB).

아래 예제는 미들웨어를 다음과 같이 구성합니다.The following example configures the middleware to:

  • 1,024바이트 이하의 응답을 캐시합니다.Cache responses smaller than or equal to 1,024 bytes.
  • 경로의 대/소문자를 구분해서 응답을 저장합니다(예를 들어 /page1/Page1을 별도로 저장합니다).Store the responses by case-sensitive paths (for example, /page1 and /Page1 are stored separately).
services.AddResponseCaching(options =>
{
    options.UseCaseSensitivePaths = true;
    options.MaximumBodySize = 1024;
});

VaryByQueryKeysVaryByQueryKeys

MVC/Web API 컨트롤러 또는 Razor Pages 페이지 모델을 사용할 때 ResponseCache 특성은 응답 캐싱을 위한 적절한 헤더를 설정하기 위해 필요한 매개 변수를 지정합니다.When using MVC/Web API controllers or Razor Pages page models, the ResponseCache attribute specifies the parameters necessary for setting the appropriate headers for response caching. 미들웨어가 반드시 필요한 ResponseCache 특성의 유일한 매개 변수는 VaryByQueryKeys로, 이 매개 변수는 실제 HTTP 헤더와 일치하지 않습니다.The only parameter of the ResponseCache attribute that strictly requires the middleware is VaryByQueryKeys, which doesn't correspond to an actual HTTP header. 자세한 내용은 ResponseCache 특성을 참고하시기 바랍니다.For more information, see ResponseCache Attribute.

ResponseCache 특성을 사용하지 않을 경우, VaryByQueryKeys 기능을 사용해서 응답 캐싱을 변경할 수 있습니다.When not using the ResponseCache attribute, response caching can be varied with the VaryByQueryKeys feature. 사용 된 ResponseCachingFeature 에서 직접 합니다 IFeatureCollectionHttpContext:Use the ResponseCachingFeature directly from the IFeatureCollection of the HttpContext:

var responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>();
if (responseCachingFeature != null)
{
    responseCachingFeature.VaryByQueryKeys = new[] { "MyKey" };
}

*VaryByQueryKeys 와 동일한 단일 값을 지정하면 모든 요청 쿼리 매개 변수에 따라 캐시가 변경됩니다.Using a single value equal to * in VaryByQueryKeys varies the cache by all request query parameters.

응답 캐싱 미들웨어에서 사용되는 HTTP 헤더HTTP headers used by Response Caching Middleware

미들웨어에 의한 응답 캐싱은 HTTP 헤더를 이용해서 구성됩니다.Response caching by the middleware is configured using HTTP headers.

헤더Header 설명Details
AuthorizationAuthorization 이 헤더가 존재할 경우 응답이 캐시되지 않습니다.The response isn't cached if the header exists.
캐시 제어Cache-Control 미들웨어는 public 캐시 지시문으로 표시된 캐싱 응답만 고려합니다.The middleware only considers caching responses marked with the public cache directive. 다음 매개 변수로 캐싱을 제어하십시오.Control caching with the following parameters:
  • 최대 처리 기간max-age
  • max-stale†max-stale†
  • 최소 새로min-fresh
  • must-revalidatemust-revalidate
  • 캐시 없음no-cache
  • 아니요-저장소no-store
  • 만 경우-캐시only-if-cached
  • privateprivate
  • publicpublic
  • 기간s-maxage
  • proxy-revalidate‡proxy-revalidate‡
max-stale에 제한이 지정되지 않으면 미들웨어는 아무런 작업도 하지 않습니다.†If no limit is specified to max-stale, the middleware takes no action.
proxy-revalidatemust-revalidate와 동일한 효과를 갖습니다.proxy-revalidate has the same effect as must-revalidate.

자세한 내용은 RFC 7231: 요청 Cache-Control 지시문을 참고하시기 바랍니다.For more information, see RFC 7231: Request Cache-Control Directives.
PragmaPragma 요청에 지정된 Pragma: no-cache 헤더는 Cache-Control: no-cache와 동일한 효과를 갖습니다.A Pragma: no-cache header in the request produces the same effect as Cache-Control: no-cache. 이 헤더는 Cache-Control 헤더가 존재할 경우, 지정된 관련 지시문에 의해 재정의됩니다.This header is overridden by the relevant directives in the Cache-Control header, if present. HTTP/1.0에 대한 하위 호환성을 감안하기 위한 헤더입니다.Considered for backward compatibility with HTTP/1.0.
Set-cookieSet-Cookie 이 헤더가 존재할 경우 응답이 캐시되지 않습니다.The response isn't cached if the header exists. 하나 이상의 쿠키를 설정하는 요청 처리 파이프라인의 모든 미들웨어는 응답 캐싱 미들웨어가 응답을 캐싱하지 못하게 합니다(예를 들어 쿠키 기반 TempData 공급자).Any middleware in the request processing pipeline that sets one or more cookies prevents the Response Caching Middleware from caching the response (for example, the cookie-based TempData provider).
VaryVary Vary 헤더는 다른 헤더를 이용해서 캐싱된 응답을 변경하기 위해서 사용됩니다.The Vary header is used to vary the cached response by another header. 예를 들어, Vary: Accept-Encoding 헤더가 지정된 요청과 Accept-Encoding: gzip 헤더가 지정된 요청에 대한 응답을 별도로 캐시하는 Accept-Encoding: text/plain 헤더를 지정해서 인코딩된 응답을 캐시할 수 있습니다.For example, cache responses by encoding by including the Vary: Accept-Encoding header, which caches responses for requests with headers Accept-Encoding: gzip and Accept-Encoding: text/plain separately. 헤더 값이 *인 응답은 절대로 저장되지 않습니다.A response with a header value of * is never stored.
ExpiresExpires 이 헤더에 의해 낡은 것으로 간주되는 응답은 다른 Cache-Control 헤더에 의해서 재정의되지 않는 한 저장되거나 조회되지 않습니다.A response deemed stale by this header isn't stored or retrieved unless overridden by other Cache-Control headers.
-None-If-matchIf-None-Match 값이 *가 아니고 응답의 ETag가 제공된 모든 값과 일치하지 않으면 전체 응답이 캐시에서 제공됩니다.The full response is served from cache if the value isn't * and the ETag of the response doesn't match any of the values provided. 그렇지 않으면 304(수정되지 않음) 응답이 제공됩니다.Otherwise, a 304 (Not Modified) response is served.
If-수정-이후If-Modified-Since If-None-Match 헤더가 존재하지 않으면, 캐시된 응답 날짜가 제공된 값보다 새로운 경우 전체 응답이 캐시에서 제공됩니다.If the If-None-Match header isn't present, a full response is served from cache if the cached response date is newer than the value provided. 그렇지 않으면 304(수정되지 않음) 응답이 제공됩니다.Otherwise, a 304 (Not Modified) response is served.
DateDate 캐시에서 응답을 제공할 때, 원본 응답이 Date 헤더를 제공하지 않으면 미들웨어에 의해 설정됩니다.When serving from cache, the Date header is set by the middleware if it wasn't provided on the original response.
Content-LengthContent-Length 캐시에서 응답을 제공할 때, 원본 응답이Content-Length 헤더를 제공하지 않으면 미들웨어에 의해 설정됩니다.When serving from cache, the Content-Length header is set by the middleware if it wasn't provided on the original response.
보존 기간Age 원본 응답이 전송한 Age 헤더는 무시됩니다.The Age header sent in the original response is ignored. 캐시된 응답을 제공할 때 미들웨어가 새로운 값을 계산합니다.The middleware computes a new value when serving a cached response.

캐싱에서 요청 Cache-Control 지시문 사용Caching respects request Cache-Control directives

미들웨어는 HTTP 1.1 캐싱 사양의 규칙을 준수합니다.The middleware respects the rules of the HTTP 1.1 Caching specification. 그리고 이 규칙은 캐시가 클라이언트에 의해서 전송된 유효한 Cache-Control 헤더를 준수할 것을 요구합니다.The rules require a cache to honor a valid Cache-Control header sent by the client. 사양에 따라 클라이언트는no-cache 헤더 값을 설정한 요청을 전송함으로써 모든 요청에 대해 서버가 새로운 응답을 생성하도록 강제할 수 있습니다.Under the specification, a client can make requests with a no-cache header value and force the server to generate a new response for every request. 현재 미들웨어를 사용할 때 이 캐싱 동작을 개발자가 제어할 수 있는 방법은 없으며, 그 이유는 미들웨어가 공식 캐싱 사양을 따르고 있기 때문입니다.Currently, there's no developer control over this caching behavior when using the middleware because the middleware adheres to the official caching specification.

캐싱 동작을 보다 세세히 제어하려면 ASP.NET Core의 다른 캐싱 기능을 살펴보십시오.For more control over caching behavior, explore other caching features of ASP.NET Core. 다음 항목을 참고하시기 바랍니다.See the following topics:

문제 해결Troubleshooting

캐싱이 예상과 다르게 동작한다면 응답이 캐싱 가능하고 캐시에서 제공될 수 있는지 확인하시기 바랍니다.If caching behavior isn't as expected, confirm that responses are cacheable and capable of being served from the cache. 요청의 수신 헤더와 응답의 송신 헤더를 점검해보십시오.Examine the request's incoming headers and the response's outgoing headers. 디버깅에 도움이 되도록 로깅을 활성화하시기 바랍니다.Enable logging to help with debugging.

캐싱 동작을 테스트하거나 문제를 해결할 때, 브라우저가 원하지 않는 방식으로 캐싱에 영향을 주는 요청 헤더를 설정할 수도 있습니다.When testing and troubleshooting caching behavior, a browser may set request headers that affect caching in undesirable ways. 예를 들어 페이지를 새로 고칠 때 브라우저가 Cache-Control 헤더를 no-cache 또는 max-age=0로 설정할 수 있습니다.For example, a browser may set the Cache-Control header to no-cache or max-age=0 when refreshing a page. 다음 도구를 사용하면 명시적으로 요청 헤더를 설정할 수 있고 캐싱 테스트에도 적합합니다.The following tools can explicitly set request headers and are preferred for testing caching:

캐싱 조건Conditions for caching

  • 요청의 결과로 200(OK) 상태 코드가 설정된 서버 응답을 받아야 합니다.The request must result in a server response with a 200 (OK) status code.
  • 요청 메서드가 GET 또는 HEAD여야 합니다.The request method must be GET or HEAD.
  • 정적 파일 미들웨어 같은 터미널 미들웨어는 반드시 응답 캐싱 미들웨어보다 먼저 응답을 처리해야 합니다.Terminal middleware, such as Static File Middleware, must not process the response prior to the Response Caching Middleware.
  • Authorization 헤더가 없어야 합니다.The Authorization header must not be present.
  • Cache-Control 헤더의 매개 변수가 유효해야 하고 응답이 public으로 표시되어야 하며 private로 표시되지 않아야 합니다.Cache-Control header parameters must be valid, and the response must be marked public and not marked private.
  • Pragma: no-cache가 있으면 Cache-Control 헤더가 Pragma 헤더를 덮어쓰므로 Cache-Control 헤더가 없는 경우 no-cache header가 없어야 합니다.The Pragma: no-cache header must not be present if the Cache-Control header isn't present, as the Cache-Control header overrides the Pragma header when present.
  • Set-Cookie 헤더가 없어야 합니다.The Set-Cookie header must not be present.
  • Vary 헤더의 매개 변수가 유효해야 하고 *가 아니어야 합니다.Vary header parameters must be valid and not equal to *.
  • Content-Length 헤더의 값이 (설정된 경우) 응답 본문의 크기와 일치해야 합니다.The Content-Length header value (if set) must match the size of the response body.
  • IHttpSendFileFeature 가 사용되지 않아야 합니다.The IHttpSendFileFeature isn't used.
  • 응답이 Expires 헤더와 max-ages-maxage 캐시 지시문에 지정된 것보다 오래되면 안 됩니다.The response must not be stale as specified by the Expires header and the max-age and s-maxage cache directives.
  • 응답 버퍼링 성공 해야 하며 응답의 크기 구성 보다 작을 수 해야 또는 기본 SizeLimit입니다.Response buffering must be successful, and the size of the response must be smaller than the configured or default SizeLimit.
  • 응답은 RFC 7234 사양에 따라 캐시 가능해야 합니다.The response must be cacheable according to the RFC 7234 specifications. 예를 들어 no-store 지시문이 요청 또는 응답 헤더 필드에 없어야 합니다.For example, the no-store directive must not exist in request or response header fields. 자세한 내용은 RFC 7234Section 3: Storing Responses in Caches를 참고하시기 바랍니다.See Section 3: Storing Responses in Caches of RFC 7234 for details.

참고

교차 사이트 요청 위조(CSRF, Cross-Site Request Forgery) 방지를 위한 보안 토큰을 생성하는 Antiforgery 시스템은 Cache-ControlPragma 헤더를 no-cache로 설정하기 때문에 응답이 캐시되지 않습니다.The Antiforgery system for generating secure tokens to prevent Cross-Site Request Forgery (CSRF) attacks sets the Cache-Control and Pragma headers to no-cache so that responses aren't cached. HTML 폼 요소에 대한 Antiforgery 토큰을 비활성화시키는 방법에 대한 정보는 ASP.NET Core Antiforgery 구성을 참고하시기 바랍니다.For information on how to disable antiforgery tokens for HTML form elements, see ASP.NET Core antiforgery configuration.

추가 자료Additional resources