File tĩnh (Static files) trong ASP.NET Core
Nguồn: Static files in ASP.NET Core
Static files (file tĩnh), còn được gọi là static assets (tài nguyên tĩnh), là các file trong ứng dụng ASP.NET Core không được tạo ra động. Thay vào đó, chúng được phục vụ trực tiếp cho client theo yêu cầu, chẳng hạn như các file HTML, CSS, hình ảnh và JavaScript.
Để bật xử lý static file trong ASP.NET Core (phiên bản 8.0), gọi UseStaticFiles.
Theo mặc định, static file được lưu trong thư mục web root của project. Thư mục mặc định là {CONTENT ROOT}/wwwroot, trong đó {CONTENT ROOT} là content root của ứng dụng. Chỉ các file trong thư mục wwwroot mới có thể truy cập được, vì vậy bạn không cần lo lắng về phần còn lại của code.
Khi chạy, static web asset được trả về bởi Static File Middleware (phần mềm trung gian file tĩnh) khi được yêu cầu cùng với các header thay đổi tài sản và loại nội dung. Các header ETag, Last-Modified và Content-Type được đặt.
Static File Middleware cho phép phục vụ static file và được sử dụng bởi ứng dụng khi UseStaticFiles được gọi trong pipeline xử lý request của ứng dụng. Các file được phục vụ từ đường dẫn được chỉ định trong IWebHostEnvironment.WebRootPath hoặc WebRootFileProvider, mặc định là thư mục web root, thường là wwwroot.
Bạn cũng có thể phục vụ static web asset từ các project và package được tham chiếu.
Thay đổi thư mục web root
Sử dụng phương thức UseWebRoot nếu bạn muốn thay đổi web root. Để biết thêm thông tin, xem ASP.NET Core fundamentals overview.
Ngăn publish các file trong wwwroot bằng cách sử dụng phần tử <Content> project item trong file project. Ví dụ sau ngăn publish nội dung trong wwwroot/local và các thư mục con:
<ItemGroup> <Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" /> </ItemGroup>
Phương thức CreateBuilder đặt content root thành thư mục hiện tại:
var builder = WebApplication.CreateBuilder(args);
Trong request processing pipeline sau khi gọi UseHttpsRedirection, gọi UseStaticFiles để cho phép phục vụ static file từ web root của ứng dụng:
app.UseStaticFiles();
Static file có thể truy cập được thông qua một đường dẫn tương đối so với web root.
Để truy cập hình ảnh tại wwwroot/images/favicon.png:
- Định dạng URL:
https://{HOST}/images/{FILE NAME} - Ví dụ:
- URL tuyệt đối:
https://localhost:5001/images/favicon.png - URL tương đối gốc:
images/favicon.png
Trong Razor Pages và ứng dụng MVC, ký tự tilde ~ trỏ đến web root. Trong ví dụ sau, ~/images/favicon.png tải hình ảnh từ thư mục wwwroot/images:
<link rel="icon" type="image/png" href="~/images/favicon.png" />
Static files trong môi trường không phải Development
Khi chạy ứng dụng cục bộ, static web asset chỉ được bật trong môi trường Development. Để bật static file cho các môi trường khác ngoài Development trong quá trình phát triển và kiểm tra cục bộ (ví dụ: môi trường Staging), gọi UseStaticWebAssets trên WebApplicationBuilder:
Gọi UseStaticWebAssets cho đúng môi trường để tránh kích hoạt tính năng trong production, vì nó phục vụ file từ các vị trí riêng biệt trên đĩa khác với từ project.
if (builder.Environment.IsStaging())
{
builder.WebHost.UseStaticWebAssets();
}Phục vụ file ngoài thư mục web root qua UseStaticFiles
Xét cấu trúc thư mục sau với static file nằm ngoài web root của ứng dụng trong thư mục ExtraStaticFiles:
wwwrootcssimagesjsExtraStaticFilesimagesred-rose.jpg
Một request có thể truy cập red-rose.jpg bằng cách cấu hình một instance mới của Static File Middleware:
using Microsoft.Extensions.FileProviders;
Trong request processing pipeline sau khi gọi UseStaticFiles:
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles")),
RequestPath = "/static-files"
});Trong đoạn code trên, cấu trúc thư mục ExtraStaticFiles được công khai thông qua đoạn URL static-files. Một request tới https://{HOST}/StaticFiles/images/red-rose.jpg sẽ phục vụ file red-rose.jpg.
Phục vụ file từ nhiều vị trí
Gọi UseStaticFiles hai lần để phục vụ file từ cả wwwroot và ExtraStaticFiles:
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"))
});Cập nhật WebRootFileProvider để bao gồm thư mục ExtraStaticFiles bằng cách sử dụng CompositeFileProvider. Điều này cho phép Image Tag Helper áp dụng phiên bản cho hình ảnh trong thư mục ExtraStaticFiles:
using Microsoft.Extensions.FileProviders;
var webRootProvider = new PhysicalFileProvider(builder.Environment.WebRootPath);
var newPathProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "ExtraStaticFiles"));
var compositeProvider = new CompositeFileProvider(webRootProvider, newPathProvider);
app.Environment.WebRootFileProvider = compositeProvider;Đặt HTTP response headers
Sử dụng StaticFileOptions để đặt HTTP response header. Ngoài việc cấu hình Static File Middleware để phục vụ static file, đoạn code sau đặt header Cache-Control thành 604.800 giây (một tuần):
using Microsoft.AspNetCore.Http;
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", "public, max-age=604800");
}
});Phân quyền file tĩnh (Static file authorization)
Khi ứng dụng áp dụng fallback authorization policy, yêu cầu xác thực cho tất cả các request không chỉ định rõ authorization policy, bao gồm cả request cho static file sau khi Authorization Middleware xử lý request. Các template ASP.NET Core cho phép truy cập ẩn danh vào static file bằng cách gọi UseStaticFiles trước khi gọi UseAuthorization. Khi Static File Middleware được gọi trước authorization middleware:
- Không có kiểm tra authorization nào được thực hiện trên static file.
- Static file được phục vụ bởi Static File Middleware, chẳng hạn như những file trong web root (thường là
wwwroot), có thể truy cập công khai.
Để phục vụ static file dựa trên authorization:
- Xác nhận rằng ứng dụng đặt fallback authorization policy để yêu cầu người dùng đã xác thực.
- Lưu trữ static file ngoài web root của ứng dụng.
- Sau khi gọi
UseAuthorization, gọiUseStaticFiles, chỉ định đường dẫn đến thư mục static file bên ngoài web root.
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.FileProviders;
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
// ...
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.ContentRootPath, "SecureStaticFiles")),
RequestPath = "/static-files"
});Directory browsing (Duyệt thư mục)
Directory browsing cho phép liệt kê thư mục trong các thư mục được chỉ định.
Directory browsing bị tắt theo mặc định vì lý do bảo mật.
Bật directory browsing với các API sau:
AddDirectoryBrowserUseDirectoryBrowser
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
builder.Services.AddDirectoryBrowser();
// ...
var fileProvider = new PhysicalFileProvider(
Path.Combine(builder.Environment.WebRootPath, "images"));
var requestPath = "/DirectoryImages";
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = fileProvider,
RequestPath = requestPath
});Đoạn code trên cho phép duyệt thư mục wwwroot/images bằng URL https://{HOST}/DirectoryImages với các liên kết đến từng file và thư mục.
Phục vụ tài liệu mặc định (Default documents)
Đặt trang mặc định cung cấp cho khách truy cập một điểm khởi đầu trên trang web. Để phục vụ một file mặc định từ wwwroot mà không yêu cầu URL request phải bao gồm tên file, gọi phương thức UseDefaultFiles:
app.UseDefaultFiles();
Với UseDefaultFiles, các request đến một thư mục trong wwwroot sẽ tìm kiếm:
default.htmdefault.htmlindex.htmindex.html
File đầu tiên tìm thấy trong danh sách sẽ được phục vụ như thể request đã bao gồm tên file.
Đoạn code sau thay đổi tên file mặc định thành default-document.html:
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("default-document.html");
app.UseDefaultFiles(options);Kết hợp static files, tài liệu mặc định và duyệt thư mục
UseFileServer kết hợp chức năng của UseStaticFiles, UseDefaultFiles và tùy chọn UseDirectoryBrowser.
Gọi UseFileServer để bật phục vụ static file và file mặc định:
app.UseFileServer();
Đoạn code sau bật phục vụ static file, file mặc định và directory browsing:
builder.Services.AddDirectoryBrowser(); // ... app.UseFileServer(enableDirectoryBrowsing: true);
Map file extensions sang MIME types
Sử dụng FileExtensionContentTypeProvider.Mappings để thêm hoặc sửa đổi ánh xạ từ phần mở rộng file sang MIME content type. Trong ví dụ sau, một số phần mở rộng file được ánh xạ sang các MIME type đã biết. Phần mở rộng .rtf được thay thế và .mp4 bị xóa:
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
// ...
// Thiết lập content type tùy chỉnh - liên kết phần mở rộng file với MIME type
var provider = new FileExtensionContentTypeProvider();
// Thêm ánh xạ mới
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Thay thế ánh xạ hiện có
provider.Mappings[".rtf"] = "application/x-msdownload";
// Xóa video MP4
provider.Mappings.Remove(".mp4");
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = provider
});Non-standard content types (Loại nội dung không tiêu chuẩn)
Static File Middleware hiểu gần 400 loại nội dung file đã biết. Nếu người dùng yêu cầu một file với loại file không rõ, Static File Middleware chuyển request đến middleware tiếp theo trong pipeline. Nếu không có middleware nào xử lý request, phản hồi 404 Not Found được trả về.
Đoạn code sau bật phục vụ các content type không rõ và hiển thị file không rõ như một hình ảnh:
app.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "image/png"
});Bật ServeUnknownFileTypes là một rủi ro bảo mật. Nó bị tắt theo mặc định và không khuyến khích sử dụng. Ánh xạ phần mở rộng file sang MIME type cung cấp một giải pháp thay thế an toàn hơn để phục vụ file với các phần mở rộng không tiêu chuẩn.
Các cân nhắc bảo mật cho static file
UseDirectoryBrowser và UseStaticFiles có thể rò rỉ thông tin bí mật. Rất khuyến nghị tắt directory browsing trong production. Xem xét cẩn thận các thư mục nào được bật thông qua UseStaticFiles hoặc UseDirectoryBrowser. Toàn bộ thư mục và các thư mục con của nó sẽ có thể truy cập công khai. Lưu trữ các file phù hợp để phục vụ công khai trong một thư mục chuyên dụng, chẳng hạn như <content_root>/wwwroot. Tách các file này khỏi các MVC view, Razor Pages, file cấu hình, v.v.
- URL cho nội dung được hiển thị với
UseDirectoryBrowservàUseStaticFilesphụ thuộc vào độ phân biệt chữ hoa chữ thường và các hạn chế ký tự của hệ thống file bên dưới. Ví dụ, Windows không phân biệt chữ hoa chữ thường, nhưng macOS và Linux thì có. - Các ứng dụng ASP.NET Core được host trong IIS sử dụng ASP.NET Core Module để chuyển tiếp tất cả request đến ứng dụng, bao gồm cả static file request. IIS static file handler không được sử dụng.
- Đặt các file code, bao gồm
.csvà.cshtml, bên ngoài web root của project ứng dụng. Điều này ngăn code phía server bị rò rỉ.