ASP.NET Core의 고정 파일Static files in ASP.NET Core

작성자: Rick AndersonScott AddieBy Rick Anderson and Scott Addie

HTML, CSS, 이미지 및 JavaScript와 같은 정적 파일은 ASP.NET Core 앱이 클라이언트에 직접 제공하는 자산입니다.Static files, such as HTML, CSS, images, and JavaScript, are assets an ASP.NET Core app serves directly to clients. 일부 구성은 이러한 파일을 제공하는 데 필수적입니다.Some configuration is required to enable to serving of these files.

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

정적 파일 제공Serve static files

정적 파일은 프로젝트의 웹 루트 디렉터리 내에 저장됩니다.Static files are stored within your project's web root directory. 기본 디렉터리는 <content_root>/wwwroot이지만, UseWebRoot 메서드를 통해 변경할 수 있습니다.The default directory is <content_root>/wwwroot, but it can be changed via the UseWebRoot method. 자세한 정보는 콘텐츠 루트웹 루트를 참조하세요.See Content root and Web root for more information.

앱의 웹 호스트에서 콘텐츠 루트 디렉터리를 인식하도록 해야 합니다.The app's web host must be made aware of the content root directory.

WebHost.CreateDefaultBuilder 메서드는 콘텐츠 루트를 현재 디렉터리로 설정합니다.The WebHost.CreateDefaultBuilder method sets the content root to the current directory:

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
}

정적 파일은 웹 루트를 기준으로 하는 경로를 통해 액세스할 수 있습니다.Static files are accessible via a path relative to the web root. 예를 들어 웹 응용 프로그램 프로젝트 템플릿에는 wwwroot 폴더 내에 여러 폴더를 포함합니다.For example, the Web Application project template contains several folders within the wwwroot folder:

  • wwwrootwwwroot
    • csscss
    • imagesimages
    • jsjs

images 하위 폴더에 있는 파일에 액세스하기 위한 URI 형식은 http://<server_address>/images/<image_file_name> 입니다.The URI format to access a file in the images subfolder is http://<server_address>/images/<image_file_name>. 예: http://localhost:9189/images/banner3.svg.For example, http://localhost:9189/images/banner3.svg.

.NET Framework를 대상으로 하는 경우 Microsoft.AspNetCore.StaticFiles 패키지를 프로젝트에 추가합니다.If targeting .NET Framework, add the Microsoft.AspNetCore.StaticFiles package to your project. .NET Core를 대상으로 하는 경우는 Microsoft.AspNetCore.All metapackage가 이 패키지를 포함합니다.If targeting .NET Core, the Microsoft.AspNetCore.All metapackage includes this package.

정적 파일을 제공할 수 있도록 미들웨어를 구성합니다.Configure the middleware which enables the serving of static files.

웹 루트 내부에 있는 파일을 제공합니다Serve files inside of web root

Startup.Configure 내부에 UseStaticFiles 메서드를 호출합니다.Invoke the UseStaticFiles method within Startup.Configure:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();
}

매개 변수가 없는 UseStaticFiles 메서드 오버로드는 웹 루트에 있는 파일을 제공 가능으로 표시합니다.The parameterless UseStaticFiles method overload marks the files in web root as servable. 다음 표시는 wwwroot/images/banner1.svg를 참조합니다.The following markup references wwwroot/images/banner1.svg:

<img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" />

웹 루트 외부에 있는 파일을 제공합니다Serve files outside of web root

제공할 정적 파일이 웹 루트 외부에 있는 디렉터리 계층 구조를 고려합니다.Consider a directory hierarchy in which the static files to be served reside outside of the web root:

  • wwwrootwwwroot
    • csscss
    • imagesimages
    • jsjs
  • MyStaticFilesMyStaticFiles
    • imagesimages
      • banner1.svgbanner1.svg

요청은 정적 파일 미들웨어를 다음과 같이 구성하여 banner1.svg 파일에 액세스할 수 있습니다.A request can access the banner1.svg file by configuring the static file middleware as follows:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); // For the wwwroot folder

    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
        RequestPath = "/StaticFiles"
    });
}

위의 코드에서 MyStaticFiles 디렉터리 계층 구조가 StaticFiles URI 세그먼트를 통해 공개적으로 노출됩니다.In the preceding code, the MyStaticFiles directory hierarchy is exposed publicly via the StaticFiles URI segment. http://<server_address>/StaticFiles/images/banner1.svg에 대한 요청은 banner1.svg 파일을 제공합니다.A request to http://<server_address>/StaticFiles/images/banner1.svg serves the banner1.svg file.

다음 표시는 MyStaticFiles/images/banner1.svg를 참조합니다.The following markup references MyStaticFiles/images/banner1.svg:

<img src="~/StaticFiles/images/banner1.svg" alt="ASP.NET" class="img-responsive" />

HTTP 응답 헤더 설정Set HTTP response headers

StaticFileOptions 개체는 HTTP 응답 헤더를 설정하는 데 사용할 수 있습니다.A StaticFileOptions object can be used to set HTTP response headers. 웹 루트에서 제공되는 정적 파일을 구성하는 것 외에도 다음 코드는 Cache-Control 헤더를 설정합니다.In addition to configuring static file serving from the web root, the following code sets the Cache-Control header:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = ctx =>
        {
            // Requires the following import:
            // using Microsoft.AspNetCore.Http;
            ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=600");
        }
    });
}

HeaderDictionaryExtensions.Append 메서드는 Microsoft.AspNetCore.Http 패키지에 있습니다.The HeaderDictionaryExtensions.Append method exists in the Microsoft.AspNetCore.Http package.

파일은 10분(600초) 동안 공개적으로 캐시할 수 있습니다.The files have been made publicly cacheable for 10 minutes (600 seconds):

추가된 캐시 제어 헤더를 보여 주는 응답 헤더

정적 파일 권한 부여Static file authorization

정적 파일 미들웨어는 권한 부여 검사를 제공하지 않습니다.The static file middleware doesn't provide authorization checks. wwwroot 아래의 항목을 비롯한 제공되는 모든 파일은 공개적으로 사용할 수 있습니다.Any files served by it, including those under wwwroot, are publicly accessible. 권한 부여를 기준으로 파일을 제공하려면 다음을 수행합니다.To serve files based on authorization:

  • wwwroot 외부의 항목 및 정적 파일 미들웨어에 액세스할 수 있는 모든 디렉터리를 저장합니다. 그리고Store them outside of wwwroot and any directory accessible to the static file middleware and
  • 권한 부여가 적용되는 동작 메서드를 통해 제공합니다.Serve them via an action method to which authorization is applied. FileResult 개체를 반환합니다.Return a FileResult object:
[Authorize]
public IActionResult BannerImage()
{
    var file = Path.Combine(Directory.GetCurrentDirectory(), 
                            "MyStaticFiles", "images", "banner1.svg");

    return PhysicalFile(file, "image/svg+xml");
}

디렉터리 검색 사용Enable directory browsing

디렉터리 검색을 사용하면 웹앱 사용자가 지정된 디렉터리 내 디렉터리 목록 및 파일을 볼 수 있습니다.Directory browsing allows users of your web app to see a directory listing and files within a specified directory. 기본적으로 디렉터리 검색은 보안상의 이유로 비활성화되어 있습니다(고려할 사항 참조).Directory browsing is disabled by default for security reasons (see Considerations). Startup.Configure에서 UseDirectoryBrowser 메서드를 호출하여 디렉터리 검색을 사용하도록 설정합니다.Enable directory browsing by invoking the UseDirectoryBrowser method in Startup.Configure:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); // For the wwwroot folder

    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
        RequestPath = "/MyImages"
    });

    app.UseDirectoryBrowser(new DirectoryBrowserOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
        RequestPath = "/MyImages"
    });
}

Startup.ConfigureServices에서 AddDirectoryBrowser 메서드를 호출하여 필요한 서비스를 추가합니다.Add required services by invoking the AddDirectoryBrowser method from Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}

위의 코드를 통해 각 파일 및 폴더에 대한 링크가 있는 URL http://<server_address>/MyImages를 사용하여 wwwroot/images 폴더의 디렉터리 검색을 사용할 수 있습니다.The preceding code allows directory browsing of the wwwroot/images folder using the URL http://<server_address>/MyImages, with links to each file and folder:

디렉터리 검색

검색을 활성화하는 경우 보안 위험에 대한 고려할 사항을 참조하세요.See Considerations on the security risks when enabling browsing.

다음 예제에서 두 UseStaticFiles 호출을 참고하세요.Note the two UseStaticFiles calls in the following example. 첫 번째 호출은 wwwroot 폴더에서 정적 파일 제공을 사용하도록 설정합니다.The first call enables the serving of static files in the wwwroot folder. 두 번째 호출은 URL http://<server_address>/MyImages를 사용하여 wwwroot/images 폴더의 디렉터리 검색을 활성화합니다.The second call enables directory browsing of the wwwroot/images folder using the URL http://<server_address>/MyImages:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); // For the wwwroot folder

    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
        RequestPath = "/MyImages"
    });

    app.UseDirectoryBrowser(new DirectoryBrowserOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
        RequestPath = "/MyImages"
    });
}

기본 문서 제공Serve a default document

기본 홈페이지를 설정하면 방문자가 사이트를 방문할 때 논리적 시작점을 제공합니다.Setting a default home page provides visitors a logical starting point when visiting your site. URI를 정규화하는 사용자 없이 기본 페이지를 제공하려면 Startup.Configure에서 UseDefaultFiles 메서드를 호출합니다.To serve a default page without the user fully qualifying the URI, call the UseDefaultFiles method from Startup.Configure:

public void Configure(IApplicationBuilder app)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();
}

중요

UseStaticFiles가 기본 파일을 제공하기 전에 UseDefaultFiles를 먼저 호출해야 합니다.UseDefaultFiles must be called before UseStaticFiles to serve the default file. UseDefaultFiles는 파일을 실제로 제공하지 않는 URL 재작성기입니다.UseDefaultFiles is a URL rewriter that doesn't actually serve the file. 파일을 제공하도록 UseStaticFiles를 통해 정적 파일 미들웨어를 활성화합니다.Enable the static file middleware via UseStaticFiles to serve the file.

UseDefaultFiles를 사용하여 다음에 대한 폴더 검색을 요청합니다.With UseDefaultFiles, requests to a folder search for:

  • default.htmdefault.htm
  • default.htmldefault.html
  • index.htmindex.htm
  • index.htmlindex.html

목록에서 첫 번째 파일이 마치 요청이 정규화된 URI인 것처럼 제공됩니다.The first file found from the list is served as though the request were the fully qualified URI. 브라우저 URL이 요청된 URI를 계속 반영합니다.The browser URL continues to reflect the URI requested.

다음 코드는 기본 파일 이름을 mydefault.html로 변경합니다.The following code changes the default file name to mydefault.html:

public void Configure(IApplicationBuilder app)
{
    // Serve my app-specific default file, if present.
    DefaultFilesOptions options = new DefaultFilesOptions();
    options.DefaultFileNames.Clear();
    options.DefaultFileNames.Add("mydefault.html");
    app.UseDefaultFiles(options);
    app.UseStaticFiles();
}

UseFileServerUseFileServer

UseFileServerUseStaticFiles, UseDefaultFilesUseDirectoryBrowser의 기능을 결합합니다.UseFileServer combines the functionality of UseStaticFiles, UseDefaultFiles, and UseDirectoryBrowser.

다음 코드는 정적 파일의 제공 및 기본 파일을 활성화합니다.The following code enables the serving of static files and the default file. 디렉터리 검색 기능이 활성화되지 않았습니다.Directory browsing isn't enabled.

app.UseFileServer();

다음 코드는 매개 변수가 없는 오버로드에서 디렉터리 검색을 활성화하여 빌드합니다.The following code builds upon the parameterless overload by enabling directory browsing:

app.UseFileServer(enableDirectoryBrowsing: true);

다음 디렉터리 계층 구조를 고려합니다.Consider the following directory hierarchy:

  • wwwrootwwwroot
    • csscss
    • imagesimages
    • jsjs
  • MyStaticFilesMyStaticFiles
    • imagesimages
      • banner1.svgbanner1.svg
    • default.htmldefault.html

다음 코드는 정적 파일, 기본 파일 및 MyStaticFiles의 디렉터리 검색을 활성화합니다.The following code enables static files, default files, and directory browsing of MyStaticFiles:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); // For the wwwroot folder

    app.UseFileServer(new FileServerOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
        RequestPath = "/StaticFiles",
        EnableDirectoryBrowsing = true
    });
}

EnableDirectoryBrowsing 속성 값이 true인 경우 AddDirectoryBrowser를 호출해야 합니다.AddDirectoryBrowser must be called when the EnableDirectoryBrowsing property value is true:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}

URL은 파일 계층 구조 및 이전 코드를 사용하여 다음과 같이 확인합니다.Using the file hierarchy and preceding code, URLs resolve as follows:

URIURI 응답Response
http://<server_address>/StaticFiles/images/banner1.svghttp://<server_address>/StaticFiles/images/banner1.svg MyStaticFiles/images/banner1.svgMyStaticFiles/images/banner1.svg
http://<server_address>/StaticFileshttp://<server_address>/StaticFiles MyStaticFiles/default.htmlMyStaticFiles/default.html

MyStaticFiles 디렉터리에 기본 이름이 지정된 파일이 없는 경우 http://<server_address>/StaticFiles는 클릭 가능한 링크와 함께 디렉터리 목록을 반환합니다.If no default-named file exists in the MyStaticFiles directory, http://<server_address>/StaticFiles returns the directory listing with clickable links:

정적 파일 목록

참고

UseDefaultFilesUseDirectoryBrowser는 후행 슬래시가 없는 URL http://<server_address>/StaticFiles를 사용하여 http://<server_address>/StaticFiles/ 로의 클라이언트 쪽 리디렉션을 트리거합니다.UseDefaultFiles and UseDirectoryBrowser use the URL http://<server_address>/StaticFiles without the trailing slash to trigger a client-side redirect to http://<server_address>/StaticFiles/. 후행 슬래시 추가를 확인하세요.Notice the addition of the trailing slash. 문서 내에서 상대 URL은 후행 슬래시가 없는 잘못된 것으로 간주됩니다.Relative URLs within the documents are deemed invalid without a trailing slash.

FileExtensionContentTypeProviderFileExtensionContentTypeProvider

FileExtensionContentTypeProvider 클래스는 MIME 콘텐츠 형식에 대한 파일 확장명 매핑 역할을 수행하는 Mappings 속성을 포함합니다.The FileExtensionContentTypeProvider class contains a Mappings property serving as a mapping of file extensions to MIME content types. 다음 샘플에서는 여러 파일 확장명이 알려진 MIME 형식에 등록됩니다.In the following sample, several file extensions are registered to known MIME types. .rtf 확장은 대체되며 .mp4는 제거됩니다.The .rtf extension is replaced, and .mp4 is removed.

public void Configure(IApplicationBuilder app)
{
    // Set up custom content types - associating file extension to MIME type
    var provider = new FileExtensionContentTypeProvider();
    // Add new mappings
    provider.Mappings[".myapp"] = "application/x-msdownload";
    provider.Mappings[".htm3"] = "text/html";
    provider.Mappings[".image"] = "image/png";
    // Replace an existing mapping
    provider.Mappings[".rtf"] = "application/x-msdownload";
    // Remove MP4 videos.
    provider.Mappings.Remove(".mp4");

    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
        RequestPath = "/MyImages",
        ContentTypeProvider = provider
    });

    app.UseDirectoryBrowser(new DirectoryBrowserOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
        RequestPath = "/MyImages"
    });
}

MIME 콘텐츠 형식을 참조하세요.See MIME content types.

비표준 콘텐츠 형식Non-standard content types

정적 파일 미들웨어는 거의 400가지의 알려진 파일 콘텐츠 형식을 이해합니다.The static file middleware understands almost 400 known file content types. 사용자가 알 수 없는 파일 형식의 파일을 요청하는 경우 정적 파일 미들웨어는 HTTP 404(찾을 수 없음) 응답을 반환합니다.If the user requests a file of an unknown file type, the static file middleware returns a HTTP 404 (Not Found) response. 디렉터리 검색을 사용하는 경우 파일에 대한 링크가 표시됩니다.If directory browsing is enabled, a link to the file is displayed. URI는 HTTP 404 오류를 반환합니다.The URI returns an HTTP 404 error.

다음 코드는 알 수 없는 형식 제공을 사용하도록 설정하고 알 수 없는 파일을 이미지로 렌더링합니다.The following code enables serving unknown types and renders the unknown file as an image:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(new StaticFileOptions
    {
        ServeUnknownFileTypes = true,
        DefaultContentType = "image/png"
    });
}

위의 코드를 사용하면 알 수 없는 콘텐츠 형식인 파일에 대한 요청은 이미지로 반환됩니다.With the preceding code, a request for a file with an unknown content type is returned as an image.

경고

ServeUnknownFileTypes를 사용하도록 설정하면 보안 위험이 발생합니다.Enabling ServeUnknownFileTypes is a security risk. 기본적으로 비활성화되어 있으며 사용은 권장되지 않습니다.It's disabled by default, and its use is discouraged. FileExtensionContentTypeProvider는 비표준 확장명을 가진 파일을 제공하는 것보다 안전한 대체 방법을 제공합니다.FileExtensionContentTypeProvider provides a safer alternative to serving files with non-standard extensions.

고려 사항Considerations

경고

UseDirectoryBrowserUseStaticFiles는 비밀 정보를 누출 할 수 있습니다.UseDirectoryBrowser and UseStaticFiles can leak secrets. 프로덕션 환경에서 디렉터리 검색을 비활성화하는 것이 좋습니다.Disabling directory browsing in production is highly recommended. UseStaticFiles 또는 UseDirectoryBrowser를 통해 어떤 디렉터리가 활성화되었는지 주의 깊게 검토합니다.Carefully review which directories are enabled via UseStaticFiles or UseDirectoryBrowser. 전체 디렉터리와 해당 하위 디렉터리는 공개적으로 액세스할 수 있습니다.The entire directory and its sub-directories become publicly accessible. <content_root>/wwwroot와 같이 전용 디렉터리에 공개적으로 제공하는 데 적합한 파일을 저장합니다.Store files suitable for serving to the public in a dedicated directory, such as <content_root>/wwwroot. MVC 뷰, Razor 페이지(2.x에만 해당), 구성 파일 등으로 이러한 파일을 구분합니다.Separate these files from MVC views, Razor Pages (2.x only), configuration files, etc.

  • UseDirectoryBrowserUseStaticFiles로 노출된 콘텐츠에 대한 URL은 대/소문자 구분 및 기본 파일 시스템의 문자 제한이 적용됩니다.The URLs for content exposed with UseDirectoryBrowser and UseStaticFiles are subject to the case sensitivity and character restrictions of the underlying file system. 예를 들어 Windows는 대/소문자를 구분하지 않는 반면 macOS 및 Linux는 그렇지 않습니다.For example, Windows is case insensitive—macOS and Linux aren't.

  • IIS에서 호스팅되는 ASP.NET Core 앱은 ASP.NET Core 모듈을 사용하여 정적 파일 요청을 비롯한 모든 요청을 앱에 전달합니다.ASP.NET Core apps hosted in IIS use the ASP.NET Core Module to forward all requests to the app, including static file requests. IIS 정적 파일 처리기는 사용되지 않습니다.The IIS static file handler isn't used. 모듈에서 처리하기 전에는 요청을 처리할 수 없습니다.It has no chance to handle requests before they're handled by the module.

  • 서버 또는 웹 사이트 수준에서 IIS 정적 파일 처리기를 제거하려면 IIS 관리자에서 다음 단계를 완료합니다.Complete the following steps in IIS Manager to remove the IIS static file handler at the server or website level:

    1. 모듈 기능으로 이동합니다.Navigate to the Modules feature.
    2. 목록에서 StaticFileModule을 선택합니다.Select StaticFileModule in the list.
    3. 동작 사이드바에서 제거를 클릭합니다.Click Remove in the Actions sidebar.

경고

IIS 정적 파일 처리기가 사용되도록 설정된 경우 ASP.NET Core 모듈이 올바르게 구성된 경우, 정적 파일이 제공됩니다.If the IIS static file handler is enabled and the ASP.NET Core Module is configured incorrectly, static files are served. 이는 예를 들어 web.config 파일이 배포되지 않는 경우에 발생합니다.This happens, for example, if the web.config file isn't deployed.

  • 코드 파일(.cs.cshtml 포함)을 앱 프로젝트의 웹 루트 외부에 배치합니다.Place code files (including .cs and .cshtml) outside of the app project's web root. 따라서 논리적 분리가 앱의 클라이언트 쪽 콘텐츠 및 서버 기반 코드 사이에 만들어집니다.A logical separation is therefore created between the app's client-side content and server-based code. 그러면 서버 쪽 코드가 유출되지 않습니다.This prevents server-side code from being leaked.

추가 자료Additional resources