如何写在这里http://developer.yahoo.com/performance/rules.html
对于静态组件:通过设置远期Expires标头
来实施“永不过期”策略
我可以获得性能,避免http请求,响应为“304”
在正式比赛中!文档我可以看到如何设置cache-controll指令,但我如何设置远期的Expires头?
最好的问候尼古拉
编辑:感谢重播,现在也可以使用!这里有班级:
CONF /路由
# Static files
GET /assets/stylesheets/img/:name controllers.StaticFilesController.getBoostrapImg(name)
GET /assets/images/*name controllers.StaticFilesController.getImg(name)
GET /assets/stylesheets/*name controllers.StaticFilesController.getCss(name)
GET /assets/javascripts/*name controllers.StaticFilesController.getJs(name)
控制器/ StaticFilesController.java
package controllers;
import org.apache.http.impl.cookie.DateUtils;
import java.util.*;
import play.mvc.*;
import services.FileName;
import play.*;
public class StaticFilesController extends Controller {
private static String nextYearString = StaticFilesController
.getNextYearAsString();
public static Result getImg(String path) {
FileName fileName = new FileName(path);
response().setHeader(EXPIRES, nextYearString);
response().setContentType("image/" + fileName.extension());
return ok(Play.application().getFile("/public/images/" + path));
}
public static Result getBoostrapImg(String path) {
FileName fileName = new FileName(path);
response().setHeader(EXPIRES, nextYearString);
response().setContentType("image/" + fileName.extension());
return ok(Play.application().getFile(
"/public/images/" + fileName.filename() + "."
+ fileName.extension()));
}
public static Result getCss(String path) {
response().setHeader(EXPIRES, nextYearString);
response().setContentType("text/css");
return ok(Play.application().getFile("/public/stylesheets/" + path));
}
public static Result getJs(String path) {
response().setHeader(EXPIRES, nextYearString);
response().setContentType("application/x-javascript");
return ok(Play.application().getFile("/public/javascripts/" + path));
}
private static String getNextYearAsString() {
Calendar calendar = new GregorianCalendar();
calendar.add(Calendar.YEAR, 1);
return DateUtils.formatDate(calendar.getTime());
}
}
服务/ FileName.java
package services;
/**
* This class assumes that the string used to initialize fullPath has a
* directory path, filename, and extension. The methods won't work if it
* doesn't.
*/
public class FileName {
private String fullPath;
private char pathSeparator, extensionSeparator;
public FileName(String str, char sep, char ext) {
fullPath = str;
pathSeparator = sep;
extensionSeparator = ext;
}
public FileName(String str)
{
fullPath = str;
pathSeparator = '/';
extensionSeparator = '.';
}
public String extension() {
int dot = fullPath.lastIndexOf(extensionSeparator);
return fullPath.substring(dot + 1);
}
public String filename() { // gets filename without extension
int dot = fullPath.lastIndexOf(extensionSeparator);
int sep = fullPath.lastIndexOf(pathSeparator);
return fullPath.substring(sep + 1, dot);
}
public String path() {
int sep = fullPath.lastIndexOf(pathSeparator);
return fullPath.substring(0, sep);
}
}
以及 views / main.scala.html
@(skin: String)(content: Html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>LibreTitan</title>
<link rel="stylesheet" media="screen" href="@routes.StaticFilesController.getCss("bootstrap/bootstrap.min.css")">
@if(skin != null && !skin.equals("")) {
<link rel="stylesheet" media="screen" href="@routes.StaticFilesController.getCss(skin+".min.css")">
}
<link rel="shortcut icon" type="image/png" href="@routes.StaticFilesController.getImg("favicon.png")">
<script async src="@routes.StaticFilesController.getJs("jquery-1.9.0.min.js")"></script>
<script async src="@routes.StaticFilesController.getJs("bootstrap.min.js")"></script>
</head>
<body>
<div class="container">
@content
</div>
</body>
</html>
答案 0 :(得分:1)
Never expire
政策意味着应该在您的回复中添加Expire
标题,这个日期是在不久的将来,例如10年后的例子。您可以在Play中轻松完成此操作,如Manipulating the response
doc中所述。例如:
public static Result index() {
response().setHeader(EXPIRES, "Thu, 16 Feb 2023 20:00:00 GMT");
return ok("<h1>Hello World!</h1>");
}
当然,将过期日期定为String
,您应该使用某种方法动态计算它,您可以使用org.joda.time.DateTime
(在Play中提供)及其方法执行此操作,例如:{{3} }。最重要的是应该最终格式化为RFC 1123
日期格式。
修改,当然您可以返回不同类型的结果 - 也是plusYears(int years)
(&#39;结果&#39;部分)中所述的二进制结果,以检查所有可用选项查看以下API:doc它可以是:ok(Content content)
- 在呈现某些视图时很常见,ok(java.io.File content)
,ok(java.io.InputStream content)
等。
我绝对建议不要使用Play来提供far future static contents
(以及任何其他静态,公共内容)。虽然你可以很容易地做到,如上所述,恕我直言,它需要处理任何单个图像,脚本,风格......等等的所有请求,这是对Play资源的多余浪费。
考虑为该作业(nginx,lighthttpd,Apache)使用通用... HTTP服务器,或者甚至更好地使用分布式CDN。在这种情况下,您的应用程序可以关注执行其逻辑而不是搜索磁盘上的样式表。
PS 请记住,如果您使用Play而不是HTTP服务器,要添加从/public
文件夹提供的新静态内容,您需要重新启动应用程序,因此,至少要确保将它们保存在应用程序的某个专用文件夹中,这样您就可以在不停止应用程序的情况下添加/删除/替换它们。