靜態(tài)文件(如 HTML、CSS、圖像和 JavaScript)是 ASP.NET Core 應(yīng)用直接提供給客戶端的資產(chǎn)。 需要進行一些配置才能提供這些文件。
靜態(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 文件夾中的多個文件夾:
用于訪問 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)文件的中間件。
調(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 根目錄。
考慮一個目錄層次結(jié)構(gòu),其中要提供的靜態(tài)文件位于 Web 根目錄之外:
按如下方式配置靜態(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" />
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 秒):
靜態(tài)文件中間件不提供授權(quán)檢查。 可公開訪問由靜態(tài)文件中間件提供的任何文件,包括 wwwroot 下的文件。 根據(jù)授權(quán)提供文件:
通過目錄瀏覽,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 請求文件夾搜索:
將請求視為完全限定 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 結(jié)合了 UseStaticFiles、UseDefaultFiles 和 UseDirectoryBrowser 的功能。
以下代碼提供靜態(tài)文件和默認文件。 未啟用目錄瀏覽。
C#
app.UseFileServer();
以下代碼通過啟用目錄瀏覽基于無參數(shù)重載進行構(gòu)建:
C#
app.UseFileServer(enableDirectoryBrowsing: true);
考慮以下目錄層次結(jié)構(gòu):
以下代碼啟用靜態(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.svg | MyStaticFiles/images/banner1.svg |
http://<server_address>/StaticFiles | MyStaticFiles/default.html |
如果 MyStaticFiles 目錄中不存在默認命名文件,則 http://<server_address>/StaticFiles 返回包含可單擊鏈接的目錄列表:
備注
UseDefaultFiles 和 UseDirectoryBrowser 使用不帶尾部反斜杠的 URL http://<server_address>/StaticFiles 觸發(fā)客戶端并重定向到 http://<server_address>/StaticFiles/。 注意添加尾部反斜杠。 無尾部反斜杠,文檔中的相對 URL 被視為無效。
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)容類型。
靜態(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)和配置文件等分開
警告
如果啟用了 IIS 靜態(tài)文件處理程序且 ASP.NET Core 模塊配置不正確,則會提供靜態(tài)文件。 例如,如果未部署 web.config 文件,則會發(fā)生這種情況。
更多建議: