基于nginx中的动态Content-Type过期标头

时间:2013-01-31 16:54:37

标签: nginx http-headers content-type http-caching expires-header

我有一个PHP网站,其中一些内容是用户生成的。例如,用户可以上传已调整大小并可以请求的照片。我想在我的nginx配置中根据MIME类型(Expires响应头)指定Content-Type标头(用于缓存)。

这是我当前的配置(我的主机会自动添加http{}server{}):

charset utf-8;

types {
    text/css            css;
    text/javascript     js;
}

gzip on;
gzip_types text/html text/css text/javascript application/json image/svg+xml;

location / {
    if (!-e $request_filename) {
        rewrite  .  /index.php last;
        break;
    }


    set $expire 0;

    if ($upstream_http_content_type = image/jpeg) { set $expire 1; }
    if ($upstream_http_content_type = image/png) { set $expire 1; }
    if ($upstream_http_content_type = image/gif) { set $expire 1; }
    if ($upstream_http_content_type = image/svg+xml) { set $expire 1; }
    if ($upstream_http_content_type = text/css) { set $expire 1; }
    if ($upstream_http_content_type = text/javascript) { set $expire 1; }

    if ($expire = 1) {
        expires max;
    }
}

这适用于静态文件(例如.png个文件 - 它们获得正确的Expires标头),但它对index.php的动态生成内容没有影响(没有Expires总而言之。有人知道我做错了吗?

1 个答案:

答案 0 :(得分:1)

location块中,当您将请求传递给php web app时,无处可去,所以我可以假设您在其他地方执行此操作,例如在location块中,就像这样:

location /index.php {
   # your code
}

当用户请求存在的静态文件时,您的配置会计算出第一个if指令并且一切顺利。当用户请求动态文件然后nginx输入您的第一个if块时,问题就开始了:

if (!-e $request_filename) {
    rewrite  .  /index.php last;
    break;
} 

这里发生了什么?您正在使用带有last指令的rewrite标记以及nginx的doc对此有何看法?

last - 完成当前重写指令的处理并重新启动该过程(包括重写),并搜索所有可用位置的URI匹配。

根据此规范,当文件是动态的时,你重写了index.php并且执行离开if阻止甚至整个location阻止并跟随if阻止检查{ {1}}甚至没有检查过。我认为它会找到content-type以获取网址location,并且您没有设置/index.php

你了解这个问题的解释吗?

对此的解决方法是移动/复制您的顺序expires max块以检查if以将配置传递执行的地方放到php web app(index.php)...或删除{{1如果没有任何其他麻烦,请从content-type指令进行标记。

Okey,所以我答应对你的conf文件做一点修复:用这两个来改变你的last块:

rewrite

第一个location块用于您的location /index.php { if ($upstream_http_content_type ~ "(image/jpeg)|(image/png)|(image/gif)|(image/svg+xml)|(text/css)|(text/javascript)") { expires max; } if ($sent_http_content_type ~ "(image/jpeg)|(image/png)|(image/gif)|(image/svg+xml)|(text/css)|(text/javascript)") { expires max; } } location / { if ($upstream_http_content_type ~ "(image/jpeg)|(image/png)|(image/gif)|(image/svg+xml)|(text/css)|(text/javascript)") { expires max; } if ($sent_http_content_type ~ "(image/jpeg)|(image/png)|(image/gif)|(image/svg+xml)|(text/css)|(text/javascript)") { expires max; } try_files $uri /index.php =404; } 和动态响应,而第二个用于静态文件。在第二个中,我们添加标头location作为上游标头和标准标头(只是为了确定)。我在这里使用一个index.php块来表示您在配置中使用正则表达式模式匹配定义的所有类型。最后我们使用expires max指令,这意味着如果有可能获得基于url的静态文件,它将获得并以其他方式尝试url /index.php或只返回http 404.第一个位置块仅对于网址if。 我在config try_files指令中找不到任何应该指向应用程序的根文件夹的指令。尝试添加此项(root doc)。

我希望这能解决你的问题。