Xitrum学习笔记10 - 静态文件Static Files
在磁盘上的静态文件(Static Files)
Xitrum项目路径结构
config public favicon.ico robots.txt 404.html 500.html img myimage.png css mystyle.css js myscript.js src build.sbt
Xitrum会自动注册 public/ 下的文件和路径。它们的URL格式是:
/img/myimage.png /css/mystyle.css /css/mystyle.min.css
引用它们的方法,publicUrl:
<img src={publicUrl("img/myimage.png")} />
在开发环境上引用普遍版本(本例为mystyle.css),在生产环境上使用最小版本(本例为mystyle.min.css)
<img src={publicUrl("css", "mystyle.css", "mystyle.min.css")} />
把静态文件传给action,使用 respondFile
respondFile("<绝对路径>") respondFile("<相对于当前工作路径的路径>")
要优化静态文件的使用效率,就要避免不需要的文件能被正则表达式过滤器(pathRegex)查找到。
如果请求的url不能匹配pathRegex,Xitrum返回响应404。
pathRegex在 config/xitrum.conf进行设置
index.html fallback
如果一个URL没有对应的路径(Action)存在,那么Xitrum会试着找 public/这个URL/index.tml。如果这个index.html存在,将被返回给客户端。
404和500的html文件
public/404.html和500.html是用来处理没找到和处理出错的请求的。可以通过以下方式使用自定义的处理Action
import xitrum.Action import xitrum.annotation.{Error404, Error500} @Error404 class My404ErrorHandlerAction extends Action { def execute() { if (isAjax) jsRespond("alert(" + jsEscape("Not Found") + ")") else renderInlineView("Not Found") } } @Error500 class My500ErrorHandlerAction extends Action { def execute() { if (isAjax) jsRespond("alert(" + jsEscape("Internal Server Error") + ")") else renderInlineView("Internal Server Error") } }
响应状态码 在action被执行之前 就已经设置好了,所以不用自己再设置
使用classpath中WebJar文件中的源文件
1. WebJars
WebJars以jar包的形式包装了很多客户端web库文件(如jQuery和Bootstrap),可以利用maven、SBT、Gradle等工具在项目中添加这些库的依赖
webjars官网:http://www.webjars.org/
要使用WebJars中的静态文件,如 Underscore.js,
1)要先在build.sbt中声明
libraryDependencies += "org.webjars" % "underscorejs" % "1.6.0-3"
2)然后在 .jade 模板文件中
script(src={webJarsUrl("underscorejs/1.6.0", "underscore.js", "underscore-min.js")})
Xitrum会自动在开发环境中使用underscore.js,在生产环境中使用underscore-min.js。
结果类似于:/webjars/underscorejs/1.6.0/underscore.js?XOKgP8_KIpqz9yUqZ1aVzw
如果在开发和生产环境都使用相同的文件,则
script(src={webJarsUrl("underscorejs/1.6.0/underscore.js")})
依赖包会自动下载(一般路径是 /Users/user/.ivy2),
可以使用sbt xitrum-package然后在target/xitrum/lib下查看依赖包以及所开发项目的jar包(如xitrum-new_2.12-1.0-SNAPSHOT.jar)。
如果依赖包版本与期望不符,可以在build.sbt中设置 dependencyOverrides以替代libraryDependencies中的版本。例如已经选择使用了jQuery2但必须使用jQuery1:
dependencyOverrides += "org.webjars" % "jquery" % "1.11.3"
2. 通过WebJar在jar包中保存源文件
例如要把 myimage.png通过 WebJar保存到mylib库中相关的jar包里:
META-INF/resources/webjars/mylib/1.0/myimage.png
在使用时,<img src={webJarsUrl("mylib/1.0/myimage.png")} />
在开发和生产环境中相应的URL是 /webjars/mylib/1.0/myimage.png?xyz123
3. 返回在classpath中的文件
要向客户端响应返回在classpath jar包或路径中的文件内容,即使该文件没有保存在WebJars库里,使用
respondResource("相对于classpath的路径")
示例:
respondResource("akka/actor/Actor.class") respondResource("META-INF/resources/webjars/underscorejs/1.6.0/underscore.js") respondResource("META-INF/resources/webjars/underscorejs/1.6.0/underscore-min.js")
客户端缓存 ETag 和 max-age
Xitrum会为磁盘上或是classpath中的静态文件自动添加 Etag。
小文件的ETag是文件内容的MD5,ETags被缓存起来供以后使用。缓存项的key是(file path,modified time)。
因为modified time在不同的server上可能不同,一个集群中的每一个web server都有它自己的本地ETag缓存。
publicUrl和webJarsUrl自动把ETag添加到它们问文件生成的URL上。如:
webJarsUrl("jquery/2.1.1/jquery.min.js") => /webjars/jquery/2.1.1/jquery.min.js?0CHJg71ucpG0OlzB-y6-mQ
Xitrum将响应头信息中的 max-age和Expire设置为1年。当磁盘上的文件变化时,它的修改时间就会改变,
因此由publicUrl和webJarsUrl生成的URL也会变化。相应地,它的ETag缓存也会因缓存项key的变化而改变
GZIP
Xitrum自动以gzip压缩文本响应内容,Xitrum会检查Content-Type头以确定响应内容是否为文本(text/html, xml/application)
Xitrum一直以gzip压缩静态文本文件,但是对于动态的文本响应,出于整体性能原因,它不会压缩小于1K的响应内容。
服务端缓存
为避免从磁盘上装载文件,Xitrum利用最近最少使用的算法把小的静态文件缓存到内存中。
可以通过config/xitrum.conf中的small_static_file_size_in_kb和max_cached_small_static_files进行配置