我正在尝试控制我的nodejs app中的静态文件缓存标头,如此处所述https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers#conditional-requests。我想使用“etag”/“if-none-match”方法。
问题是我的请求在Heroku上始终未定义“if-none-match”标头。它在我的开发服务器上运行良好。
这是我的fs.readFile调用:
fs.readFile(SERVERDIR+'client/'+file, function(err, data) {
if(err) {
console.log(currTime() + ' [STATIC] ... ' + err);
if(err.code === "ENOENT") { // file is simply missing
resNotFound(res,'file not found',err);
} else { // other error; could be EACCES or anything
resInternalError(res,'internal server error',err);
}
}
else {
fs.stat(SERVERDIR+'client/'+file, function (err, stat) {
if (err) {
resInternalError(res,'internal server error',err);
}
else {
var etag = stat.size + '-' + Date.parse(stat.mtime);
res.setHeader('Last-Modified', stat.mtime);
if(LOGSTATIC) { console.log(currTime() + ' [STATIC] ... etag : ' + etag); }
if(LOGSTATIC) { console.log(currTime() + ' [STATIC] ... req.if-none-match : ' + req.headers['if-none-match']); }
if(LOGSTATIC) { console.log(req.headers); }
if (req.headers['if-none-match'] === etag) {
res.statusCode = 304;
res.end();
}
else {
res.setHeader('Content-Length', data.length);
res.setHeader('ETag', etag);
res.statusCode = 200;
res.end(data);
}
}
});
}
});
以下是单个文件请求的heroku日志:
2013-05-03T10:32:05.461070+00:00 heroku[router]: at=info method=GET path=/css/common.css host=www.chess-hub.net fwd="193.252.157.50" dyno=web.1 connect=0ms service=5ms status=200 bytes=792
2013-05-03T10:32:05.455619+00:00 app[web.1]: 10:32 [STATIC] ... serving client//css/common.css
2013-05-03T10:32:05.457981+00:00 app[web.1]: { 'x-request-start': '1367577125454',
2013-05-03T10:32:05.457981+00:00 app[web.1]: 'x-forwarded-port': '80',
2013-05-03T10:32:05.455443+00:00 app[web.1]: 10:32 [STATIC] client file request
2013-05-03T10:32:05.457981+00:00 app[web.1]: 'x-forwarded-proto': 'http',
2013-05-03T10:32:05.456127+00:00 app[web.1]: 10:32 [STATIC] ... req if-none-match : undefined
2013-05-03T10:32:05.457981+00:00 app[web.1]: cookie: 'BCSI-CS-56C420186ECC3F22=2',
2013-05-03T10:32:05.457981+00:00 app[web.1]: dnt: '1',
2013-05-03T10:32:05.457981+00:00 app[web.1]: 'cache-control': 'max-age=0',
2013-05-03T10:32:05.457981+00:00 app[web.1]: 'x-forwarded-for': '193.252.157.50',
2013-05-03T10:32:05.456046+00:00 app[web.1]: 10:32 [STATIC] ... etag : 792-1367572582000
2013-05-03T10:32:05.457981+00:00 app[web.1]: host: 'www.chess-hub.net',
2013-05-03T10:32:05.458231+00:00 app[web.1]: accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' }
2013-05-03T10:32:05.457981+00:00 app[web.1]: 'user-agent': 'Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0',
2013-05-03T10:32:05.458231+00:00 app[web.1]: 'accept-language': 'fr-FR,en-us;q=0.5',
2013-05-03T10:32:05.457981+00:00 app[web.1]: connection: 'close',
2013-05-03T10:32:05.458231+00:00 app[web.1]: 'accept-encoding': 'gzip, deflate',
......就是这样。保存日志时不确定heroku是如何截断输出的。
感谢您的帮助。
编辑:看起来这个问题与我通过代理连接的事实有某种联系。当我跳过它时,heroku日志正确显示“if-none-match”标题,我的应用程序返回http / 304代码。我的代理为请求添加了一个巨大的“代理授权”令牌,它可能是标题中的长度限制吗?
答案 0 :(得分:0)
有两个问题可能导致您观察到的行为:
Etag
和Last-Modifed
是冗余标头,您应该只使用其中一个。由于您同时返回,因此浏览器可能会发送if-modified-since
而不是if-none-match
。在您的情况下,Last-Modified
标头似乎比Etags
更合适。Cache-Control:public, max-age=2592000, must-revalidate
或Expires
(但不是两者)另请参阅this guide以获取有关缓存控制标头的详细说明。
像firebug这样的工具可以帮助您大大检查浏览器发送和接收的标题。