[鐵人賽Day05] ASP.Net Core MVC 進化之路 - 靜態檔案(Static Files)

在ASP.Net MVC5中,

對於靜態檔案的存取並沒有特別的規範。

而在ASP.Net Core裡,

對於靜態檔案存取有特定的限制,

這樣的設計也有助於安全性的提升。

靜態檔案泛指瀏覽器在呈現完整畫面時所需要的資源檔案,

常見有的.html、.js、.css、.jpg、.png等。

 

在ASP.Net Core 中,

將靜態檔案預設存放於wwwroot的目錄中,

ASP.Net Core 2.1版會自動將UseStaticFiles中介層加入Startup裡,

透過調整UseStaticFiles呼叫的順序,

可以避免經過不需要的Middleware所造成的浪費

 

我們試著在wwwroot裡新增一個index.html。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    index.html in wwwroot directory.
</body>
</html>

輸出結果如下:

假設我想存取其他目錄的靜態檔案呢?

我們在專案目錄下新增一個MyHtmlFiles目錄,

並在MyHtmlFiles底下新增一個mypage.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    mypage.html in MyHtmlFiles Directory.
</body>
</html>

完成後於瀏覽器進行測試,

會發現找不到檔案。

 

嘗試加入目錄名稱後一樣找不到。

 

若要允取瀏覽器(Client)存取指定的目錄下的檔案(MyHtmlFiles),

可於Startup中的Configure做設定。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles();
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "MyHtmlFiles")),
        RequestPath = "/myfiles"
    });
}

透過自訂請求路徑(/myfiles)存取MyHtmlFiles的目錄,

可以防止伺服器檔案路徑洩漏問題,

 

調整後再編譯執行一次。

設定預設檔案

我們可以使用UseDefaultFiles設定預設路由,

官方預設將下列幾種當作預設名稱

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

我們也可以自訂預設名稱

DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();

option.DefaultFileNames.Clear()會將預設的檔案名稱移除,

在這邊有一點要注意的是預設名稱只能有一個,

因此註冊的順序會影響路由的結果。

如果在new DefaultFilesOption時沒有Clear,

加入自訂檔名時會附加到原本預設名稱集合後(如下圖)。

預設檔名在mapping時只要找到第一個符合的就會直接返回,

假設我們在wwwroot底下新增一個mydefault.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    mydefault.html in wwwroot Directory.
</body>
</html>

 

接著修改Startup的內容

DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();

開啟預設路徑會發現顯示的是index.html的內容

我們暫時將wwwroot/index.html重新命名為index1.html​,

再執行一次。

 

所以如果要針對特定目錄設定預設檔名,

建議將DefaultFileNames重設會比較好。

 

官方文件上特別提到,

UseDefaultFiles實際上是用URL rewriter幫我們做路由覆寫的動作,

但這不代表使用預設檔案就具有存取該檔案目錄的權限。

如果想要針對wwwroot外的目錄設定預設檔案,

則要另外進行設定。

app.UseDefaultFiles(new DefaultFilesOptions()
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "MyHtmlFiles")),
    RequestPath = new PathString("/myfiles")
});
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "MyHtmlFiles")),
    RequestPath = "/myfiles"
});

 

關於靜態的檔案就記錄到這邊。

參考

https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/static-files?view=aspnetcore-2.1&tabs=aspnetcore2x