3

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

这是我当前的配置(我的主机自动添加http{}and 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标题)没有影响。有人知道我做错了什么吗?

4

1 回答 1

1

在您的location块中,当您将请求传递给 php Web 应用程序时无处可去,因此我可以假设您在其他地方执行此操作,例如location像这样的块:

location /index.php {
   # your code
}

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

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

这里发生了什么?您正在使用last带有指令的标志rewrite以及 nginx 的文档对此有何评论?

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

根据此规范,当文件是动态的时,您进行了重写index.php并且执行留下了if块,甚至整个location块和if用于检查的后续块content-type都没有被检查。我想它会location为 url找到然后/index.php你没有设置expires max.

你明白这个对你的问题的解释吗?

对此的解决方案是移动/复制您的顺序if块,以检查content-type您的配置将执行传递给 php web 应用程序 (index.php) 的位置......或者如果它没有造成任何其他麻烦,last则从指令中删除标志。rewrite

好的,所以我承诺对您的 conf 文件进行一些修复: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为上游标头和标准标头(只是为了确定)。我在这里if为您在配置中使用正则表达式模式匹配定义的所有类型使用一个块。最后,我们使用try_files指令,这意味着如果可以基于 url 获取静态文件,它将被获取,并且以其他方式尝试 url /index.php 或仅返回 http 404。第一个位置块仅适用于 url /index.php。我在您的配置指令中找不到root应该指向您应用程序的根文件夹的位置。尝试添加它(root doc)。

于 2013-01-31T17:58:46.350 回答