1. 程式人生 > >asp .net core 靜態檔案資源

asp .net core 靜態檔案資源

### 前言 對靜態資源的簡單的一個概況,在《重新整理.net core 計1400篇》系列後面會深入。 ### 正文 我們在加入中介軟體是這樣寫的: ``` app.UseStaticFiles(); ``` 預設是給wwwroot提供資源。 那麼我訪問https://localhost:44330/js/site.js 資源,就可以訪問到。 ``` // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification // for details on configuring this project to bundle and minify static web assets. // Write your JavaScript code. ``` 同樣我們可以自定義路徑。 ``` app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Static")), RequestPath="/static" }); ``` 上面在根目錄下的static建立路由,路由路徑static 為標識。 訪問: https://localhost:44330/static/images/index.jpg 就能看到一張圖片了。 同樣再次訪問,https://localhost:44330/js/site.js 依然可以訪問,看了這個wwwroot 是一個釘子戶,無論如何新增還是存在的。 ``` const string cacheMaxAge = "60480"; app.UseHttpsRedirection(); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Static")), RequestPath="/static", OnPrepareResponse = ctx => { ctx.Context.Response.Headers.Append("cache-control", $"public,max-age={cacheMaxAge}"); } } ); ``` 可以設定一些快取。 ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200830102739151-1227205377.png) #### 靜態檔案授權 官方倒是提供了兩種方法。 一種是,讓靜態檔案路由放到許可權之後。 ``` app.UseAuthentication(); app.UseAuthorization(); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( Path.Combine(env.ContentRootPath, "Static")), RequestPath = "/static" }); ``` 另一種比較自定義高: ``` [Authorize] public IActionResult BannerImage() { var filePath = Path.Combine( _env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg"); return PhysicalFile(filePath, "image/jpeg"); } ``` 可以根據引數做一些邏輯變化。 但是這些方式比較影響效能,一般來說靜態檔案是開放的,而使用者上傳的檔案是通過加密的,放在儲存伺服器上。 當然小型專案,可以用用。 #### 靜態檔案目錄 Configure中新增: ``` app.UseDirectoryBrowser(new DirectoryBrowserOptions { FileProvider=new PhysicalFileProvider(Path.Combine(env.ContentRootPath,"Static")), RequestPath="/static" }); ``` 這個中介軟體注入的位置是應該在UseRouting之前的,同樣是效能問題。 然後在ConfigureServices中新增: ``` services.AddDirectoryBrowser(); ``` 效果: ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200830121202857-809887801.png) 這種方式呢,一般只是在dev環境下開啟,真正的生產環境由於安全問題就不開啟的。 #### 預設文件 ``` app.UseDefaultFiles(); app.UseStaticFiles(); ``` app.UseStaticFiles(); 才是真正的路由。 app.UseDefaultFiles(); 只是說提供一些引數,比如配置下面這些為預設項。 ``` default.htm default.html index.htm index.html ``` 其實是這樣一個過程,app.UseStaticFiles() 如果沒有找到相應的路由,那麼應該給下一個中介軟體。 如果呼叫了app.UseDefaultFiles(),那麼會去找是否存在預設項,預設是去wwwroot 下尋找上述的預設項。 預設文件可以進行修改: ``` var options = new DefaultFilesOptions(); options.DefaultFileNames.Clear(); options.DefaultFileNames.Add("mydefault.html"); app.UseDefaultFiles(options); app.UseStaticFiles(); ``` UseFileServer 結合了 UseStaticFiles、UseDefaultFiles 和 UseDirectoryBrowser(可選)的功能。 app.UseFileServer(enableDirectoryBrowsing: true); enableDirectoryBrowsing 表示是否使用UseDirectoryBrowser。 ### FileExtensionContentTypeProvider FileExtensionContentTypeProvider 類包含 Mappings 屬性,用作副檔名到 MIME 內容型別的對映。 比如說我去訪問:https://localhost:44330/static/test.myapp 我在static 下有test.mapp 這個檔案,但是靜態檔案處理並沒有去處理。 原因: ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200830125342898-977516080.png) 客服端發了這樣一個請求,人家接受這些流,但是伺服器找到到,myapp 對應的媒體型別,那麼這個時候客戶端就不會接受了,服務端也認為沒有找到。 官方給了例子: ``` 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.UseDefaultFiles(); app.UseStaticFiles(); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Static")), RequestPath = "/static", OnPrepareResponse = ctx => { ctx.Context.Response.Headers.Append("cache-control", $"public,max-age={cacheMaxAge}"); }, ContentTypeProvider= provider } ``` 給他加一個媒體型別,認為myapp 應該是一個需要下載檔案。 然後執行之,然後就會出現下載。 同樣,我們寫的是.html,如果我們不喜歡可以去寫.htm3也行。 https://localhost:44330/static/index.htm3 結果: ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200830130037153-610347375.png) 因為provider.Mappings[".htm3"] = "text/html";,.htm3被對映成了text/html,那麼客戶端就按照這種格式處理。所以模板引擎就可以多樣性,有興趣自己也可以去設計。 這就是媒體型別對映。 如果是媒體型別未知的情況下,那麼可以這樣: ``` app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Static")), RequestPath = "/static", OnPrepareResponse = ctx => { ctx.Context.Response.Headers.Append("cache-control", $"public,max-age={cacheMaxAge}"); }, ServeUnknownFileTypes = true, DefaultContentType = "image/png" } ); ``` ServeUnknownFileTypes true DefaultContentType "image/png" 讓客戶端按照圖片處理。 ![](https://img2020.cnblogs.com/blog/1289794/202008/1289794-20200830130655982-68404891.png) 但是官方給了建議。 啟用 ServeUnknownFileTypes 會形成安全隱患。 它預設處於禁用狀態,不建議使用。 FileExtensionContentTypeProvider 提供了更安全的替代方法來提供含非標準副檔名的