ASP.NET Core 中的靜態(tài)文件

2019-04-17 08:59 更新

靜態(tài)文件(如 HTML、CSS、圖像和 JavaScript)是 ASP.NET Core 應(yīng)用直接提供給客戶端的資產(chǎn)。 需要進行一些配置才能提供這些文件。

查看或下載示例代碼如何下載

提供靜態(tài)文件

靜態(tài)文件存儲在項目的 Web 根目錄中。 默認目錄是 <content_root>/wwwroot,但可通過 UseWebRoot 方法更改目錄。 有關(guān)詳細信息,請參閱內(nèi)容根目錄和 Web 根目錄。

應(yīng)用的 Web 主機必須識別內(nèi)容根目錄。

采用 WebHost.CreateDefaultBuilder 方法可將內(nèi)容根目錄設(shè)置為當前目錄:

C#

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

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

可通過 Web 根目錄的相關(guān)路徑訪問靜態(tài)文件。 例如,Web 應(yīng)用程序項目模板包含 wwwroot 文件夾中的多個文件夾:

  • wwwrootcssimagesjs

用于訪問 images 子文件夾中的文件的 URI 格式為 http://<server_address>/images/<image_file_name>。 例如,http://localhost:9189/images/banner3.svg。

如果以 .NET Framework 為目標,請將 Microsoft.AspNetCore.StaticFiles 包添加到項目。 如果以 .NET Core 為目標,Microsoft.AspNetCore.App 元包將包括此包。

配置提供靜態(tài)文件的中間件

提供 Web 根目錄內(nèi)的文件

調(diào)用 Startup.Configure 中的 UseStaticFiles 方法:

C#

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

無參數(shù) UseStaticFiles 方法重載將 Web 根目錄中的文件標記為可用。 以下標記引用 wwwroot/images/banner1.svg:

CSHTML

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

在上面的代碼中,波形符 ~/ 指向 Web 根目錄。 有關(guān)詳細信息,請參閱 Web 根目錄。

提供 Web 根目錄外的文件

考慮一個目錄層次結(jié)構(gòu),其中要提供的靜態(tài)文件位于 Web 根目錄之外:

  • wwwrootcssimagesjs
  • MyStaticFilesimagesbanner1.svg

按如下方式配置靜態(tài)文件中間件后,請求可訪問 banner1.svg 文件:

C#

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 目錄層次結(jié)構(gòu)通過 StaticFiles URI 段公開。 請求 http://<server_address>/StaticFiles/images/banner1.svg 提供 banner1.svg 文件。

以下標記引用 MyStaticFiles/images/banner1.svg:

CSHTML

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

設(shè)置 HTTP 響應(yīng)標頭

StaticFileOptions 對象可用于設(shè)置 HTTP 響應(yīng)標頭。 除配置從 Web 根目錄提供靜態(tài)文件外,以下代碼還設(shè)置 Cache-Control 標頭:

C#

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 包中。

在開發(fā)環(huán)境中可公開緩存這些文件 10 分鐘(600 秒):

已添加顯示 Cache-Control 標頭的響應(yīng)頭

靜態(tài)文件授權(quán)

靜態(tài)文件中間件不提供授權(quán)檢查。 可公開訪問由靜態(tài)文件中間件提供的任何文件,包括 wwwroot 下的文件。 根據(jù)授權(quán)提供文件:

  • 將文件存儲在 wwwroot 和靜態(tài)文件中間件可訪問的任何目錄之外。
  • 通過有授權(quán)的操作方法提供文件。 返回 FileResult 對象:C#復(fù)制[Authorize] public IActionResult BannerImage() { var file = Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles", "images", "banner1.svg"); return PhysicalFile(file, "image/svg+xml"); }

啟用目錄瀏覽

通過目錄瀏覽,Web 應(yīng)用的用戶可查看目錄列表和指定目錄中的文件。 出于安全考慮,目錄瀏覽默認處于禁用狀態(tài)(請參閱注意事項)。 調(diào)用 Startup.Configure 中的 UseDirectoryBrowser 方法來啟用目錄瀏覽:

C#

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"
    });
}

調(diào)用 Startup.ConfigureServices 中的AddDirectoryBrowser 方法來添加所需服務(wù):

C#

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

上述代碼允許使用 URL http://<server_address>/MyImages 瀏覽 wwwroot/images 文件夾的目錄,并鏈接到每個文件和文件夾:

目錄瀏覽

有關(guān)啟用瀏覽時的安全風險,請參閱注意事項

請注意以下示例中的兩個 UseStaticFiles 調(diào)用。 第一個調(diào)用提供 wwwroot 文件夾中的靜態(tài)文件。第二個調(diào)用使用 URL http://<server_address>/MyImages 瀏覽 wwwroot/images 文件夾的目錄:

C#

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"
    });
}

提供默認文檔

設(shè)置默認主頁為訪問者訪問網(wǎng)站時提供了邏輯起點。 若要在用戶不完全限定 URI 的情況下提供默認頁面,請調(diào)用 Startup.Configure 中的 UseDefaultFiles 方法:

C#

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

 重要

要提供默認文件,必須在 UseStaticFiles 前調(diào)用 UseDefaultFiles。 UseDefaultFiles 實際上用于重寫 URL,不提供文件。 通過 UseStaticFiles 啟用靜態(tài)文件中間件來提供文件。

使用 UseDefaultFiles 請求文件夾搜索:

  • default.htm
  • default.html
  • index.htm
  • index.html

將請求視為完全限定 URI,提供在列表中找到的第一個文件。 瀏覽器 URL 繼續(xù)反映請求的 URI。

以下代碼將默認文件名更改為 mydefault.html:

C#

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();
}

UseFileServer

UseFileServer 結(jié)合了 UseStaticFiles、UseDefaultFiles 和 UseDirectoryBrowser 的功能。

以下代碼提供靜態(tài)文件和默認文件。 未啟用目錄瀏覽。

C#

app.UseFileServer();

以下代碼通過啟用目錄瀏覽基于無參數(shù)重載進行構(gòu)建:

C#

app.UseFileServer(enableDirectoryBrowsing: true);

考慮以下目錄層次結(jié)構(gòu):

  • wwwrootcssimagesjs
  • MyStaticFilesimagesbanner1.svgdefault.html

以下代碼啟用靜態(tài)文件、默認文件和及 MyStaticFiles 的目錄瀏覽:

C#

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 時必須調(diào)用 AddDirectoryBrowser:

C#

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

使用文件層次結(jié)構(gòu)和前面的代碼,URL 解析如下:

URI響應(yīng)
http://<server_address>/StaticFiles/images/banner1.svgMyStaticFiles/images/banner1.svg
http://<server_address>/StaticFilesMyStaticFiles/default.html

如果 MyStaticFiles 目錄中不存在默認命名文件,則 http://<server_address>/StaticFiles 返回包含可單擊鏈接的目錄列表:

靜態(tài)文件列表

 備注

UseDefaultFiles 和 UseDirectoryBrowser 使用不帶尾部反斜杠的 URL http://<server_address>/StaticFiles 觸發(fā)客戶端并重定向到 http://<server_address>/StaticFiles/。 注意添加尾部反斜杠。 無尾部反斜杠,文檔中的相對 URL 被視為無效。

FileExtensionContentTypeProvider

FileExtensionContentTypeProvider 類包含 Mappings 屬性,用作文件擴展名到 MIME 內(nèi)容類型的映射。 在以下示例中,多個文件擴展名注冊到了已知的 MIME 類型。 替換了 .rtf 擴展名,刪除了 .mp4。

C#

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 內(nèi)容類型

非標準內(nèi)容類型

靜態(tài)文件中間件可理解近 400 種已知文件內(nèi)容類型。 如果用戶請求文件類型未知的文件,則靜態(tài)文件中間件將請求傳遞給管道中的下一個中間件。 如果沒有中間件處理請求,則返回“404 未找到”響應(yīng)。 如果啟用了目錄瀏覽,則在目錄列表中會顯示該文件的鏈接。

以下代碼提供未知類型,并以圖像形式呈現(xiàn)未知文件:

C#

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

使用前面的代碼,請求的文件含未知內(nèi)容類型時,以圖像形式返回請求。

 警告

啟用 ServeUnknownFileTypes 存在安全風險。 它默認處于禁用狀態(tài),不建議使用。FileExtensionContentTypeProvider 提供了更安全的替代方法來提供含非標準擴展名的文件。

注意事項

 警告

UseDirectoryBrowser 和 UseStaticFiles 可能會泄漏機密。 強烈建議在生產(chǎn)中禁用目錄瀏覽。請仔細查看 UseStaticFiles 或 UseDirectoryBrowser 啟用了哪些目錄。 整個目錄及其子目錄均可公開訪問。 將適合公開的文件存儲在專用目錄中,如 <content_root>/wwwroot。 將這些文件與 MVC 視圖、Razor 頁面(僅限 2.x)和配置文件等分開

  • 使用 UseDirectoryBrowser 和 UseStaticFiles 公開的內(nèi)容的 URL 受大小寫和基礎(chǔ)文件系統(tǒng)字符限制的影響。 例如,Windows 不區(qū)分大小寫 — macOS 和 Linux 卻要區(qū)分。
  • 托管于 IIS 中的 ASP.NET Core 應(yīng)用使用 ASP.NET Core 模塊將所有請求轉(zhuǎn)發(fā)到應(yīng)用,包括靜態(tài)文件請求。 未使用 IIS 靜態(tài)文件處理程序。 在模塊處理請求前,處理程序沒有機會處理請求。
  • 在 IIS Manager 中完成以下步驟,刪除服務(wù)器或網(wǎng)站級別的 IIS 靜態(tài)文件處理程序:轉(zhuǎn)到“模塊”功能。在列表中選擇 StaticFileModule。單擊“操作”側(cè)欄中的“刪除”。

 警告

如果啟用了 IIS 靜態(tài)文件處理程序且 ASP.NET Core 模塊配置不正確,則會提供靜態(tài)文件。 例如,如果未部署 web.config 文件,則會發(fā)生這種情況。

  • 將代碼文件(包括 .cs 和 .cshtml )放在應(yīng)用項目的 Web 根目錄之外。 這樣就在應(yīng)用的客戶端內(nèi)容和基于服務(wù)器的代碼間創(chuàng)建了邏輯分隔。 可以防止服務(wù)器端代碼泄漏。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號