静态文件中间件
静态文件中间件用于高效地处理和提供 HTML、CSS、JS、图片等静态资源请求,是 Web 应用开发中不可或缺的基础能力。
基本使用
快速启动
静态文件的优先级低于动态资源(Endpoint)
cangjie
import spire_web_http.*
import spire_web_hosting.*
import spire_web_staticfiles.*
main(args: Array<String>) {
let builder = WebHost.createBuilder()
let host = builder.build()
// 启用静态文件和默认文件中间件
host.useFileServer()
host.run()
return 0
}目录结构
- 我们可以通过配置
webRootPath来配置静态文件的根路径。由于配置支持环境变量、命令行参数、json。因此你可以使用上面的任意一种进行配置。 contentRootPath表示内容路径,即当前项目路径,日志日志会打印此路径webRootPath为当前项目(contentRootPath)下的wwwroot文件夹。
bash
demo/ # contentRootPath
├─ src/
│ ├─ main.cj
│ └─ ...
├─ wwwroot/ # webRootPath
│ ├─ html/
│ ├─ css/
│ ├─ index.html
│ └─ ...
└─ ...静态文件中间件
默认文件中间件,负责将/xxx.xxx请求路径路径,匹配静态文件列表
cangjie
main(args: Array<String>) {
let builder = WebHost.createBuilder()
let host = builder.build()
host.useStaticFiles()
host.run()
return 0
}默认文件中间件
默认文件中间件,负责将/请求路径,匹配默认文件列表(默认文件列表可配置)
cangjie
main(args: Array<String>) {
let builder = WebHost.createBuilder()
let host = builder.build()
host.useDefaultFiles()
host.run()
return 0
}配置项
自定义响应头
cangjie
main(args: Array<String>) {
let builder = WebHost.createBuilder()
let host = builder.build()
host.useFileServer{ options =>
options.staticFileOptions.onPrepareResponse = {context =>
context.context.response.addHeader(HeaderNames.CacheControl, "public, max-age=604800")
}
}
host.run()
return 0
}设置ContentType
如果文件类型映射是ContentTypeProvider声明以外的,将返回404。但是我们提供了多种配置方式来进行扩展。我们也可以实现IContentTypeProvider接口来进行更加灵活的控制。
处理未知的类型
统一处理所有为准的内容类型。
cangjie
main(args: Array<String>) {
let builder = WebHost.createBuilder()
let host = builder.build()
host.useFileServer { options =>
// 允许处理未知的响应类型
options.staticFileOptions.serveUnknownFileTypes = true
options.staticFileOptions.defaultContentType = "unkonwn"
}
host.run()
return 0
}扩展已知类型
框架内置了ContentTypeProvider,我们可以添加默认之外的已知类型。
cangjie
main(args: Array<String>) {
let builder = WebHost.createBuilder()
let host = builder.build()
host.useFileServer { options =>
let contentTypeProvider = ContentTypeProvider()
contentTypeProvider.mappings.add(".cj", "cangjie")
options.staticFileOptions.contentTypeProvider = contentTypeProvider
}
host.run()
return 0
}自定义文件提供程序
通过自定义文件提供程序,我们可以实现从不同的存储介质获取资源。比如我们可以通过网络从远程拉取。
cangjie
import std.fs.*
main(args: Array<String>) {
let builder = WebHost.createBuilder()
let host = builder.build()
host.useFileServer {
options => options.staticFileOptions.fileProvider = MyPhysicalFileProvider(builder.environment.webRootPath)
}
host.run()
return 0
}
public class MyPhysicalFileProvider <: IFileProvider {
private let _path: String
public init(path: String) {
_path = path
}
public func getFileInfo(file: String): IFileInfo {
let path = "${_path}${file}"
if (exists(path)) {
return PhysicalFileInfo(FileInfo(path))
} else {
return NotFoundFileInfo(path.toString())
}
}
}组合文件提供程序
支持将多个文件提供程序组合成一个,将按照注册顺序查找
cangjie
main(args: Array<String>) {
let builder = WebHost.createBuilder()
let host = builder.build()
host.useFileServer { options =>
let fileProvider = CompositeFileProvider([
PhysicalFileProvider("${builder.environment.webRootPath}/a"),
PhysicalFileProvider("${builder.environment.webRootPath}/b")])
options.staticFileOptions.fileProvider = fileProvider
}
host.run()
return 0
}