ASP.NET Core 中文文档 第三章 原理(3)静态文件处理
原文:Working with Static Files
作者:Rick Anderson
翻譯:劉怡(AlexLEWIS)
校對:謝煬(kiler398)、許登洋(Seay)、孟帥洋(書緣)
靜態文件(static files),諸如 HTML、CSS、圖片和 JavaScript 之類的資源會被 ASP.NET Core 應用直接提供給客戶端。
章節:
靜態文件服務
靜態文件授權
允許直接瀏覽目錄
默認文檔服務
UseFileServer
非標準的內容類型
擴展資源
靜態文件服務
靜態文件通常位于?web root(<content-root>/wwwroot)文件夾下。更多有關 Content root 或 Web root 的信息請訪問?intro?。你通常會把項目的當前目錄設置為 Content root,這樣項目的?web root?就可以在開發階段被明確。
public static void Main(string[] args){var host = new WebHostBuilder().UseKestrel().UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration().UseStartup<Startup>().Build();host.Run(); }靜態文件能夠被保存在網站根目錄下的任意文件夾內,并通過相對根的路徑來訪問。比方說,當你通過 Visual Studio 創建一個默認的 Web 應用程序項目,在?wwwroot?目錄下會多出幾個文件夾:css、images以及?js?文件夾。形如下例的 URL 能夠直接訪問?images?目錄下的圖片:
http://<app>/images/<imageFileName>
http://localhost:9189/images/banner3.svg
為了能夠啟用靜態文件服務,你必須配置中間件(middleware),把靜態文件中間件加入到管道內。靜態文件中間件能夠通過下述方法來配置:在你的項目中增加?Microsoft.AspNetCore.StaticFiles?包依賴,然后從?Startup.Configure?調用?UseStaticFiles?擴展方法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){app.UseStaticFiles(); }app.UseStaticFiles();?使得?web root(默認為?wwwroot)下的文件可以被訪問。隨后我將展示如何通過使用?UseStaticFiles?將其他目錄下的內容也向外提供服務。
你必須在?project.json?文件中包含 “Microsoft.AspNetCore.StaticFiles”。
注意
web root?的默認目錄是?wwwroot,但你可以通過?UseWebRoot?來設置?web root?。具體可參考?intro?。
假設你有一個有層次結構的項目,你希望其中靜態文件的位于?web root?的外部,比如:
wwwroot
css
images
...
MyStaticFiles
test.png
對于訪問?test.png?的請求,可以如此配置靜態文件中間件:
復制代碼
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){app.UseStaticFiles();app.UseStaticFiles(new StaticFileOptions() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?FileProvider = new PhysicalFileProvider( ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Path.Combine(Directory.GetCurrentDirectory(), @"MyStaticFiles")), RequestPath = new PathString("/StaticFiles") ? ? ? ? ? ? ? ? ? ? ? ? ? ?}); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
在請求?http://<app>/StaticFiles/test.png?時,就能訪問到?test.png?文件。
靜態文件授權
靜態文件模塊并?不?提供授權檢查。任何通過該模塊提供訪問的文件,包括位于?wwwroot?下的文件都是公開的。為了給文件提供授權:
將文件保存在?wwwroot?之外并將目錄設置為可被靜態文件中間件訪問到,同時——
通過一個控制器的 Action 來訪問它們,通過授權后返回?FileResult
允許直接瀏覽目錄
目錄瀏覽允許網站用戶看到指定目錄下的目錄和文件列表。基于安全考慮,默認情況下是禁用目錄訪問功能的(參考?注意事項?)。在?Startup.Configure?中調用?UseDirectoryBrowser?擴展方法可以開啟網絡應用目錄瀏覽:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){app.UseStaticFiles(); // For the wwwroot folderapp.UseStaticFiles(new StaticFileOptions(){FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\images")),RequestPath = new PathString("/MyImages")});app.UseDirectoryBrowser(new DirectoryBrowserOptions(){FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\images")),RequestPath = new PathString("/MyImages")}); }并且通過從?Startup.ConfigureServices?調用?AddDirectoryBrowser?擴展方法來增加所需服務。
public void ConfigureServices(IServiceCollection services){services.AddDirectoryBrowser(); }這段代碼允許在訪問?http://<app>/MyImages?時可瀏覽?wwwroot/images?文件夾的目錄,其中包括該文件夾下的每一個文件與文件夾:
查看關于開放訪問目錄時的安全隱患?注意事項?一節。
注意兩個?app.UseStaticFiles?調用。第一個調用請求?wwwroot?文件夾下的 CSS、圖片和 JavaScript,第二個調用通過?http://<app>/MyImages?請求瀏覽?wwwroot/images?文件夾的目錄
復制代碼
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){app.UseStaticFiles(); // For the wwwroot folder ? ? ? ? ? ? ? ? ? ? ? ? ? ? app.UseStaticFiles(new StaticFileOptions() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\images")),RequestPath = new PathString("/MyImages")});app.UseDirectoryBrowser(new DirectoryBrowserOptions(){FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\images")),RequestPath = new PathString("/MyImages")}); }默認文檔服務
設置默認首頁能給你的站點的每個訪問者提供一個起始頁。為使站點能提供默認頁,避免用戶輸入完整 URI,須在?Startup.Configure?中調用?UseDefaultFiles?擴展方法:
public void Configure(IApplicationBuilder app){app.UseDefaultFiles(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?app.UseStaticFiles(); }注意
UseDefaultFiles?必須在?UseStaticFiles?之前調用。UseDefaultFiles?只是重寫了 URL,而不是真的提供了這樣一個文件。你必須開啟靜態文件中間件(UseStaticFiles)來提供這個文件。
通過?UseDefaultFiles,請求文件夾的時候將檢索以下文件:
default.htm
default.html
index.htm
index.html
上述列表中第一個被找到的文件將返回給用戶(作為該完整 URI 的請求的應答,而此時瀏覽器 URL 將繼續顯示用戶輸入的 URI)。
下述代碼展示如何將默認文件名改為?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(); }UseFileServer
UseFileServer?包含了?UseStaticFiles?、UseDefaultFiles?和?UseDirectoryBrowser?的功能。
下面的代碼啟用了靜態文件和默認文件,但不允許直接訪問目錄:
app.UseFileServer();下面的代碼啟用了靜態文件、默認文件和目錄瀏覽功能:
app.UseFileServer(enableDirectoryBrowsing: true);查看直接提供目錄訪問時的安全風險注意事項。作為一個集合了?UseStaticFiles、UseDefaultFiles?和?UseDirectoryBrowser?方法于一體的方法,如果你希望提供?web root?之外存在的文件,你要實例化并配置一個?FileServerOptions?對象傳遞給?UseFileServer?的參數。比方說在你的應用中有如下層次的目錄:
wwwroot
css
images
...
MyStaticFiles
test.png
default.html
使用上面這個層次結構的示例,你可能希望啟用靜態文件、默認文件以及瀏覽?MyStaticFiles?目錄。下面的代碼片段演示了調用一次?FileServerOptions?來完整實現這些功能:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){app.UseStaticFiles();app.UseFileServer(new FileServerOptions() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? FileProvider = new PhysicalFileProvider( ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Path.Combine(Directory.GetCurrentDirectory(), @"MyStaticFiles")), ? ? ? RequestPath = new PathString("/StaticFiles"), ? ? ? ? ? ? ? ? ? ? ? ? ? EnableDirectoryBrowsing = true ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
如果在你從?Startup.ConfigureServices?請求調用?AddDirectoryBrowser?擴展方法時將?enableDirectoryBrowsing?置為?true,那么:
public void ConfigureServices(IServiceCollection services){services.AddDirectoryBrowser(); }使用的文件層次結構:
| http://<app>/StaticFiles/test.png | StaticFiles/test.png |
| http://<app>/StaticFiles | MyStaticFiles/default.html |
如果在?MyStaticFiles?目錄下沒有默認命名的文件,則?http://<app>/StaticFiles?將返回目錄列表,其中包含可供點擊的鏈接:
注意
UseDefaultFiles?和?UseDirectoryBrowser?將會把末尾不帶斜杠的 URL?http://<app>/StaticFiles?重新定向到?http://<app>/StaticFiles/?(末尾增加了一個斜杠)。如果末尾不帶斜杠,文檔內相對 URL 會出錯。
FileExtensionContentTypeProvider
FileExtensionContentTypeProvider?類內包含一個將文件擴展名映射到 MIME 內容類型的集合。在下面的例子中,多個文件擴展名注冊為已知的 MIME 類型,“.rtf”被替換,“.mp4”被移除。
復制代碼
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 = new PathString("/MyImages"),ContentTypeProvider = provider ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });app.UseDirectoryBrowser(new DirectoryBrowserOptions(){FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\images")),RequestPath = new PathString("/MyImages")}); }查看?MIME 內容類型。
非標準的內容類型
ASP.NET 靜態文件中間件能夠支持超過 400 種已知文件內容類型。如果用戶請求一個未知的文件類型,靜態文件中間件將返回 HTTP 404(未找到)響應。如果啟用目錄瀏覽,該文件的鏈接將會被顯示,但 URI 會返回一個 HTTP 404 錯誤。
下方代碼把不能識別的類型和文件作為圖片處理。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){app.UseStaticFiles(new StaticFileOptions{ServeUnknownFileTypes = true,DefaultContentType = "image/png"}); }根據上面的代碼,未知內容類型的文件請求將返回一張圖片。
警告
開啟?ServeUnknownFileTypes?存在安全風險,請打消這個念頭。FileExtensionContentTypeProvider?(下文將解釋)提供了更安全的非標準擴展替代。
注意事項
警告
UseDirectoryBrowser?和?UseStaticFiles?可能會泄密。我們推薦你?不要?在生產環境開啟目錄瀏覽。要小心哪些被你開啟了?UseStaticFiles或?UseDirectoryBrowser?的目錄(使得其子目錄都可被訪問)。我們建議將公開內容放在諸如?<content root>/wwwroot?這樣的目錄中,遠離應用程序視圖、配置文件等。
使用?UseDirectoryBrowser?和?UseStaticFiles?暴露的文件的 URL 是否區分大小寫以及字符限制受制于底層文件系統。比方說 Windows 是不區分大小寫的,但 macOS 和 Linux 則區分大小寫。
托管于 IIS 的 ASP.NET Core 應用程序使用 ASP.NET Core 模塊向應用程序轉發所有請求,包括靜態文件。IIS 靜態文件處理程序(IIS Static File Handler)不會被使用,因為在 ASP.NET Core 模塊處理之前它沒有任何機會來處理請求。
以下步驟可移除 IIS 靜態文件處理程序(在服務器層級或網站層級上):
導航到?模塊?功能
從列表中選中?StaticFileModule
在?操作?側邊欄中點擊?刪除
警告
如果 IIS 靜態文件處理程序開啟?并且?ASP.NET Core 模塊(ANCM)沒有被正確配置(比方說web.config?沒有部署),(也能)將會提供靜態文件。
代碼文件(包括 C# 和 Razor)應該放在應用程序項目的?web root?(默認為?wwwroot)之外的地方。這將確保您創建的應用程序能明確隔離客戶端側和服務器側源代碼,此舉能防止服務器側的代碼被泄露。
相關文章:
ASP.NET Core 中文文檔 第三章 原理(1)應用程序啟動
ASP.NET Core 中文文檔 第三章 原理(2)中間件
原文地址:http://www.cnblogs.com/dotNETCoreSG/p/aspnetcore-3_3-static-files.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
贊賞
人贊賞
總結
以上是生活随笔為你收集整理的ASP.NET Core 中文文档 第三章 原理(3)静态文件处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core 中文文档 第三
- 下一篇: 用Swashbuckle给ASP.NET