1. 程式人生 > >《ASP.NET Core 高效能系列》靜態檔案中介軟體

《ASP.NET Core 高效能系列》靜態檔案中介軟體

一、概述

  靜態檔案(如 HTML、CSS、圖片和 JavaScript等檔案)是 Web程式直接提供給客戶端的直接載入的檔案。 較比於程式動態互動的程式碼而言,其實原理都一樣(走Http協議),

ASP.NET Core中需要進行一些配置才能提供這些檔案。

二、wwwroot

  靜態檔案儲存在專案的 Web 程式的 {ContentRoot}/wwwroot目錄下,但可通過 UseWebRoot 方法更改路徑 。 

Web 應用程式專案的 wwwroot 資料夾中預設有多個資料夾 :

  • wwwroot
    • css
    • images
    • js

用於訪問 images 子資料夾中的檔案的 URI 格式為 http://<server_address>/images/<image_file_name> 。 例如, http://localhost:1189/images/banner.png

  通過以下程式碼開啟靜態檔案訪問功能(設定 {ContentRoot}/wwwroot為預設的靜態檔案工作目錄)

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

三、設定指定目錄為靜態檔案工作目錄

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); //   wwwroot 目錄

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

  注意訪問自定義的靜態檔案路徑發生變化:http://localhost:1189/GiveAName/images/banner.png

四、給靜態檔案新增客戶端快取

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    var cachePeriod = env.Production() ? "60000" : "600";
    app.UseStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = ctx =>
        {
            // 記得下面的引用:
            // using Microsoft.AspNetCore.Http;
            ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={cachePeriod}");
        }
    });
}

  如上,在生產環境中,我們給靜態檔案添加了60000(ms)的快取,即:在一分鐘內,客戶端都會從瀏覽器本地拿檔案,注意此手法,直接更新靜態檔案一時間是拿不到最新檔案的.

 

 

五、利用PhysicalFile方法讓靜態檔案的訪問可以進行鑑權

  靜態檔案中介軟體允許瀏覽器端訪問由靜態檔案中介軟體提供的所有靜態檔案(包括 wwwroot 下的檔案),我們設想實際的一個應用場景,我們上傳了一個檔案到指定目錄,而這個檔案只能當事人自己可以進行訪問,那麼如何進行許可權驗證呢?

[Authorize]//身份驗證
public IActionResult UsersOwnPictrue()
{
    var file = Path.Combine(Directory.GetCurrentDirectory(), 
                            "StaticFilesPath", "images", "my.svg");
    return PhysicalFile(file, "image/svg+xml");//返回靜態檔案
}

六、前後端分離開發中的使用

  前後端開發分離的開發模式中,前端自己負責前端的一切互動工作,不僅如此還會在後端工作沒有啟動前自己構造資料,ASP.NET Core靜態檔案中介軟體,正好可和此開發

模式進行銜接,此處省略一萬字,有一點大家比較關心的問題:如何設定專案起始頁,如何設定前端專案中的預設頁

public void Configure(IApplicationBuilder app)
{
    app.UseDefaultFiles();//必須在 UseStaticFiles 前呼叫 UseDefaultFiles。 UseDefaultFiles 實際上用於重寫 URL,不提供檔案。
    app.UseStaticFiles(); //這兩步
}
使用 UseDefaultFiles 會使用以下這些檔案作為整個專案的預設起始頁:
default.htm
default.html
index.htm
index.html
public void Configure(IApplicationBuilder app)
{
    // 使用其他檔案作為預設靜態頁面檔案
    DefaultFilesOptions options = new DefaultFilesOptions();
    options.DefaultFileNames.Clear();
    options.DefaultFileNames.Add("其他wwwroot下的.html");
    app.UseDefaultFiles(options);
    app.UseStaticFiles();
}

 

app.UseFileServer();//可將上面兩步何為一步

 

七、關於UseFileServer

  UseFileServer 整合了 UseStaticFiles、UseDefaultFiles 和 UseDirectoryBrowser(可選,如果啟用需要services.AddDirectoryBrowser())的功能,

public void Configure(IApplicationBuilder app)
{
   
    app.UseFileServer(new FileServerOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "資料夾")),
        RequestPath = "/請求名",
        EnableDirectoryBrowsing = true
    });
}
請求連線 對應路徑
http://<server_address>/請求名/images/file1.png 資料夾/images/file1.png
http://<server_address>/請求名/ 資料夾/default.html

八、開啟目錄瀏覽功能

  此功能通常不要開啟,因為比較危險,通過目錄瀏覽,Web 應用的使用者可檢視目錄列表和指定目錄中的檔案。 出於安全考慮,呼叫 Startup.Configure 中的 UseDirectoryBrowser 方法來啟用目錄瀏覽:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}
 app.UseDirectoryBrowser(new DirectoryBrowserOptions //開啟對wwwroot/images的檔案進行瀏覽的功能
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
        RequestPath = "/MyImages"
    });

九、指定指定檔案型別的MIME型別

public void Configure(IApplicationBuilder app)
{

    var provider = new FileExtensionContentTypeProvider();

    provider.Mappings[".rtf"] = "application/x-msdownload";
    // 移除指定檔案的解析
    provider.Mappings.Remove(".mp4");
    ......
}
public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(new StaticFileOptions
    {
       //未知型別的ContentType
        ServeUnknownFileTypes = true,
        DefaultContentType = "bala/your type"
    });
}

&n