Статичные файлы¶
Отправка статических файлов с диска¶
Шаблонная директория 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
для хранения статических файлов.
Для генерации ссылок на статические файлы:
/img/myimage.png
/css/mystyle.css
/css/mystyle.min.css
Используйте шаблон:
<img src={publicUrl("img/myimage.png")} />
Для работы с обычными файлами в режиме разработчика и их минимизированными версиями (например, mystyle.css и mystyle.min.css), используйте шаблон:
<img src={publicUrl("css", "mystyle.css", "mystyle.min.css")} />
Для отправки файла с диска из контроллера используйте метод respondFile
.
respondFile("/absolute/path")
respondFile("path/relative/to/the/current/working/directory")
Для оптимизации работы со статическими файлами, вы можете избежать использование не нужны файлов ограничив их маской (фильтром на основе регулярного выражения). Если запрос не будет соответствовать регулярному выражению, Xitrum ответит страницей 404 на этот зарос.
Смотри pathRegex
в config/xitrum.conf
.
index.html и обработка отсутствующих маршрутов¶
Если не существует контроллера для данного URL, например /foo/bar
(или /foo/bar/
),
Xitrum попытается найти подходящий статический файл public/foo/bar/index.html
(в директории “public”). Если файл существует, то он будет отправлен клиенту.
404 и 500¶
404.html и 500.html в директории public
используются когда маршрут не обнаружен или на сервере произошла ошибка.
Пример использования своего собственного обработчика ошибок:
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")
}
}
Код ответа устанавливается в 404 или 500 еще до того как код контроллера будет запущен, соответственно вам не нужно устанавливать его самостоятельно.
Использование файлов ресурсов в соответствии с WebJars¶
WebJars¶
WebJars предоставляет множество библиотек которые вы можете объявить как зависимости вашего проекта.
Например, для использования Underscore.js,
достаточно прописать в build.sbt
:
libraryDependencies += "org.webjars" % "underscorejs" % "1.6.0-3"
После этого, в шаблоне .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")})
Хранение файлов ресурсов внутри .jar файла согласно WebJars¶
Если вы разработчик библиотек и ваша библиотека включает myimage.png, то вы можете сохранить myimage.png внутри .jar файла. Используя WebJars, например:
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
Ответ файлом из classpath¶
Для ответа файлом находящимся внутри classpath (или внутри .jar файла), даже если файл хранится не по стандарту WebJars:
respondResource("path/relative/to/the/classpath/element")
Например:
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 автоматически добавляет Etag для статических файлов на диске и в classpath.
ETag для маленьких файлов - MD5 хэш от контента файла. Они кэшируются для последующего использования.
Ключ кэша - (путь до файла, время изменения)
. Поскольку время изменения на разных серверах
может отличаться, каждый веб сервер в кластере имеет свой собственный ETag кэш.
Для больших файлов, только время изменения используется как ETag. Такая система не совершенна поскольку идентичные файлы на разных серверах могут иметь различный ETag, но это все равно лучше чем не использовать ETag вовсе.
publicUrl
и webJarsUrl
автоматически добавляют ETag для ссылок. Например:
webJarsUrl("jquery/2.1.1/jquery.min.js")
=> /webjars/jquery/2.1.1/jquery.min.js?0CHJg71ucpG0OlzB-y6-mQ
Xitrum так же устанавливает заголовки max-age
и Expires
в значение
1 год.
Не переживайте, браузер все равно получит последнею версию файла. Потому что для
файлов хранящихся на диске, после изменении ссылка на файл меняется, т.к. генерируется с
помощью publicUrl
и webJarsUrl
. Их ETag кэш так же обновляется.
GZIP¶
Xitrum автоматически сжимает текстовые ответы. Проверяется заголовок Content-Type
для определения текстового ответа: text/html
, xml/application
и пр.
Xitrum всегда сжимает текстовые файлы, но для динамических ответов с целью повышения производительности ответы размером меньше 1 килобайта не сжимаются.
Кэш на стороне сервера¶
Для избежания загрузки файлов с диска, Xitrum кэширует маленькие файлы
(не только текстовые) в LRU кэше (вытеснение давно неиспользуемых).
Смотри small_static_file_size_in_kb
и max_cached_small_static_files
в config/xitrum.conf
.