ASP.NET Core 中的靜態檔案Static files in ASP.NET Core

Rick AndersonScott Addie 撰寫By 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 serving of these files.

檢視或下載範例程式碼 (英文) (如何下載)View or download sample code (how to download)

提供靜態檔案Serve static files

靜態檔案會儲存在專案的web 根目錄中。Static files are stored within the 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. 如需詳細資訊,請參閱內容根目錄Web 根目錄See Content root and Web root for more information.

您必須讓應用程式的 Web 主機記住內容根目錄。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)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

您可以叫用 Program.Main 內的 UseContentRoot,以將內容根目錄設定為目前的目錄:Set the content root to the current directory by invoking UseContentRoot inside of Program.Main:

public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .Build();

        host.Run();
    }        
}

靜態檔案可透過相對於web 根目錄的路徑來存取。Static files are accessible via a path relative to the web root. 例如,Web 應用程式專案範本的 wwwroot 資料夾內包含數個資料夾:For example, the Web Application project template contains several folders within the wwwroot folder:

  • wwwrootwwwroot
    • csscss
    • imagesimages
    • jsjs

若要存取 images 子資料夾的檔案,其 URI 格式為 http://<伺服器位址>/images/<影像檔名稱>。The URI format to access a file in the images subfolder is http://<server_address>/images/<image_file_name>. 例如, http://localhost:9189/images/banner3.svgFor example, http://localhost:9189/images/banner3.svg.

如以 .NET Framework 為目標,請將 Microsoft.AspNetCore.StaticFiles 套件新增至專案。If targeting .NET Framework, add the Microsoft.AspNetCore.StaticFiles package to the project. 如以 .NET Core 為目標,Microsoft.AspNetCore.All 中繼套件會包含此套件。If targeting .NET Core, the Microsoft.AspNetCore.App metapackage includes this package.

如以 .NET Framework 為目標,請將 Microsoft.AspNetCore.StaticFiles 套件新增至專案。If targeting .NET Framework, add the Microsoft.AspNetCore.StaticFiles package to the project. 如以 .NET Core 為目標,Microsoft.AspNetCore.All 中繼套件會包含此套件。If targeting .NET Core, the Microsoft.AspNetCore.All metapackage includes this package.

Microsoft.AspNetCore.StaticFiles 套件新增至專案。Add the Microsoft.AspNetCore.StaticFiles package to the project.

設定中介軟體以提供靜態檔案。Configure the middleware which enables the serving of static files.

提供 Web 根目錄內的檔案Serve files inside of web root

叫用 Startup.Configure 內的 UseStaticFiles 方法:Invoke the UseStaticFiles method within Startup.Configure:

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

無參數的 UseStaticFiles 方法多載會將web 根目錄中的檔案標記為 servable。The parameterless UseStaticFiles method overload marks the files in web root as servable. 下列標記參考 wwwroot/images/banner1.svgThe following markup references wwwroot/images/banner1.svg:

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

在上述程式碼中,波狀符號字元 ~/ 指向web 根目錄In the preceding code, the tilde character ~/ points to the web root.

提供 Web 根目錄外的檔案Serve files outside of web root

假設有一個目錄階層,其中要提供的靜態檔案位於web 根目錄外部: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"
    });
}

上述程式碼會透過 StaticFiles URI 區段公開 MyStaticFiles 目錄階層。In the preceding code, the MyStaticFiles directory hierarchy is exposed publicly via the StaticFiles URI segment. 要求 http://<伺服器位址>/StaticFiles/images/banner1.svg 時,會提供 banner1.svg 檔案。A request to http://<server_address>/StaticFiles/images/banner1.svg serves the banner1.svg file.

下列標記參考 MyStaticFiles/images/banner1.svgThe 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. 除了設定web 根目錄提供的靜態檔案外,下列程式碼也會設定 @no__t 1 標頭:In addition to configuring static file serving from the web root, the following code sets the Cache-Control header:

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

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) in the Development environment:

已新增顯示「快取控制」標頭的回應標頭

靜態檔案授權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.

  • 透過動作方法,將它們提供給已套用授權的目標。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

您的 Web 應用程式使用者可藉由目錄瀏覽功能,查看目錄清單及指定目錄內的檔案。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://<伺服器位址>/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://<伺服器位址>/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 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.htmlThe 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

UseFileServer 結合 UseStaticFilesUseDefaultFilesUseDirectoryBrowser 的功能。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 時,必須呼叫 AddDirectoryBrowserAddDirectoryBrowser 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://<伺服器位址>/StaticFiles 會傳回含有可點按連結的目錄清單:If no default-named file exists in the MyStaticFiles directory, http://<server_address>/StaticFiles returns the directory listing with clickable links:

靜態檔案清單

注意

UseDefaultFilesUseDirectoryBrowser 會從 http://{SERVER ADDRESS}/StaticFiles (不含尾端斜線) 執行用戶端重新導向至 http://{SERVER ADDRESS}/StaticFiles/ (含尾端斜線)。UseDefaultFiles and UseDirectoryBrowser perform a client-side redirect from http://{SERVER ADDRESS}/StaticFiles (without a trailing slash) to http://{SERVER ADDRESS}/StaticFiles/ (with a trailing slash). StaticFiles 目錄內的相對 URL 若未含尾端斜線則會被視為無效。Relative URLs within the StaticFiles directory are invalid without a trailing slash.

FileExtensionContentTypeProviderFileExtensionContentTypeProvider

FileExtensionContentTypeProvider 類別包含 Mappings 屬性以作為 MIME 內容類型的副檔名對應。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 副檔名,並已移除 .mp4The .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 種已知的檔案內容類型。Static File Middleware understands almost 400 known file content types. 如果使用者要求具有未知檔案類型的檔案,則靜態檔案中介軟體會將該要求傳遞至管線中的下一個中介軟體。If the user requests a file with an unknown file type, Static File Middleware passes the request to the next middleware in the pipeline. 如果沒有中介軟體處理要求,則會傳回「404 找不到」回應。If no middleware handles the request, a 404 Not Found response is returned. 如果啟用目錄瀏覽功能,則會在目錄清單中顯示檔案的連結。If directory browsing is enabled, a link to the file is displayed in a directory listing.

下列程式碼可讓您提供未知的類型,並會將未知的檔案轉譯為影像: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. 透過 UseStaticFilesUseDirectoryBrowser,仔細檢閱要啟用哪些目錄。Carefully review which directories are enabled via UseStaticFiles or UseDirectoryBrowser. 因為整個目錄和其子目錄都可供公開存取。The entire directory and its sub-directories become publicly accessible. 將檔案存放在專門公開提供的目錄,例如 <content_root>/wwwrootStore 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. 選取清單中的 StaticFileModuleSelect 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.

  • 將程式碼檔案(包括 .cscshtml)放在應用程式專案的web 根目錄外部。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