提供文件和缓存
Aqueduct可以通过返回文件的内容作为HTTP响应体来服务于文件。
FileController
FileController
的实例通过HTTP接口从文件系统服务于一个目录。任何引导请求到FileController
的路由必须包含一个*
匹配全部。
@override
Controller get entryPoint {
final router = Router();
router.route("/files/*").link(() => FileController("public/"));
return router;
}
FileController
的参数是文件系统上的目录,请求路径将被解析到该目录下。在上面的例子中,路径为/files/image.jpg
的HTTP请求将返回文件public/image.jpg
的内容。
请注意,public/
没有前导斜线,因此,目录public
必须是相对于Aqueduct应用程序所服务的目录。在实践中,这意味着你可能会有一个像这样的目录结构。
project/
pubspec.yaml
lib/
channel.dart
...
test/
...
public/
image.jpg
在 FileController
所服务的目录中添加一个前导斜线将使其相对于文件系统根目录进行解析。
如果请求的路径是一个目录,在搜索要返回的文件时,文件名 index.html
将被附加到路径中。
如果一个文件不存在,FileController
将返回404 Not Found响应。
文件的Content-Type
FileController
将根据送达文件的路径扩展名来设置HTTP响应的内容类型。默认情况下,它可以识别许多常见的扩展类型,如.html
、.css
、.jpg
、.js
。你可以给一个实例添加扩展的内容类型:
var controller = FileController("public/")
..setContentTypeForExtension("xml", ContentType("application", "xml"));
如果没有用于服务的文件的扩展项,内容类型默认为application/octet-stream
。FileController
永远不会从CodecRegistry
中调用任何编码器,但如果存储库允许对文件的内容类型进行压缩,它就会对GZIP数据进行压缩(参见CodecRegistry.add
和CodecRegistry.setAllowsCompression
)。
缓存
FileController
总是根据文件系统将响应的Last-Modified头设置为最后修改日期。 如果请求发送If-Modified-Since标头,并且自该日期以来未修改文件,则发送带有适当标头的304 Not Modified响应。
您可以提供Cache-Control标头,具体取决于要提供的文件的路径。 这是一个添加Cache-Control:public,max-age = 31536000
的示例
var policy = CachePolicy(expirationFromNow: Duration(days: 365));
var controller = FileController("public/")
..addCachePolicy(policy, (path) => path.endsWith(".css"));
FileController之外的文件服务和缓存
任何控制器都可以通过设置Response
的主体对象及其内容来为文件提供服务:
var file = File("index.html");
// 首先将内容加载到内存中...
var response = Response.ok(file.readAsStringSync())
..contentType = ContentType("application", "html");
// 或通过流传输磁盘中的内容
var response = Response.ok(file.openRead())
..encodeBody = false
..contentType = ContentType("application", "html");
重要的是要了解Aqueduct如何使用 content-types 处理响应体来服务文件内容。
你可以设置任何Response
的CachePolicy
。注意,CachePolicy
只修改响应的Cache-Control头。像 Last-Modified 和 ETag 这样的头不被添加。
var response = Response.ok("contents")
..cachePolicy = CachePolicy();