如何在 Nginx 服务器上设置“Expires”和“Cache-Control”标头?

如何在 Nginx 服务器上设置“Expires”和“Cache-Control”标头?

我有一个在 DigitalOcean droplet(nginx 服务器)上运行的 php 网站,我也使用 Cloudflare。最近,我的网站受到了一些我还不明白的问题的攻击……因为我的 CPU 使用率通常为 1-2%,但在几个小时内达到了 100%,导致我的服务器崩溃。

我的 Cloudflare 分析显示访问者数量极高 - 我确信这不是人流量。

Cloudflare 要求查看我的 nginx 错误日志和访问日志。以下是他们的回复 -

您有 2 个缓存标头,您的资产一旦存储在我们的边缘,它们就会过期。

< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

< Expires:> Thu, 19 Nov 1981 08:52:00 GMT. 

由于 Expires 标头设置为过去的某个时间,因此缓存在到达我们的边缘时就会过期。然后,您的缓存控制标头基本上表示不要在我们的边缘存储任何资产,但您启用了缓存,因此我们的边缘将继续抓取您的网站。这可能会导致看起来像是针对您的源站的 DoS 攻击。

有人能告诉我如何在 Nginx 服务器上设置 Expires 标头和 Cache-control 标头吗?

答案1

您的文件中的设置不正确php.ini

该值在默认文件中session.cache_limiter设置为,需要更改。nocachephp.ini

session.cache_limiter应该定义并设置,要么public插入公共缓存控制标头,要么插入''(空白),不插入任何缓存控制标头,然后将使用应用程序发送的标头(如果有)。

答案2

我发现,使用 Wordpress(某些主题)和其他 PHP 应用程序时,有时几乎不可能使用 PHP 正确设置标头。我的解决方案是,我只需忽略应用程序设置的标头,并用 Nginx 中我想要的内容覆盖它们。我发现这更简单、更快、更可靠。

如果您能从应用程序和 PHP 中找出如何做到这一点,那很好,但这种方式可以让您拥有很多控制权,而且很容易。使用所需模块构建 nginx 比您想象的要容易,根据我下面链接的指南,它可能可以在 30 分钟内完成。

我有一个关于如何设置 Nginx 和 Cloudflare 的指南。

缓存标头的简短版本:

  • 您需要缓存控制
  • 你不需要实用主义

对于图像,请在您的位置使用类似这样的内容 - 您需要将 headers-more 模块编译到 nginx 中。请参阅我的教程第 1 部分。

add_header Cache-Control "public, max-age=691200, s-maxage=691200";
more_clear_headers Server; more_clear_headers "Pragma"; more_clear_headers "Expires";

对于页面,我不会在 CloudFlare 上缓存,但我会使用 nginx fast_cgi 页面缓存,这在我的教程中。

对于 CloudFlare,如果您需要任何技巧,则可能需要使用页面规则,但一般来说,默认设置将缓存图像但不缓存页面。

答案3

如今,大多数使用 PHP 和 Nginx 的云服务器都将使用 PHP-FPM(或应该使用)...为了更清晰的配置,我建议保留session.cache_limiter = nocache您的配置php.ini,然后使用 Nginx 覆盖 HTTP 标头,这样更可靠。

为了SlickStack,我的开源 LEMP 脚本,我们甚至更进一步,通过普遍禁用文件中的某些缓存标头,nginx.conf如下所示:

more_clear_headers "Pragma Expires";

...这确保随机的 WordPress 插件(等)不会干扰我们的缓存标头。

然后在 Nginx 服务器块中,我们仅启用Cache-Control静态资产的标头,以确保像 Cloudflare 这样的 CDN 能够在边缘正确缓存它们:

location ~* \.(atom|bmp|bz2|css|doc|docx|eot|gif|gz|ico|jpeg|jpg|js|mid|midi|mp4|ogg|ogv|otf|png|ppt|rar|rss|rtf|svg|svgz|tar|tgz|ttc|ttf|wav|webp|woff|woff2|xls|zip)$ {
    add_header Cache-Control "public, max-age=691200";
}

这将启用大约 1 周的 TTL...但在 Cloudflare 中,您可以通过访问“缓存”选项卡并将“浏览器缓存 TTL”设置为 1 个月等来将其延长。(为了更加安全,您还可以创建一个Cloudflare 中的页面规则/wp-content/*对于所有静态资产都应从中加载的目录的任何请求,这也会强制 Edge Cache TTL 为 1 个月。)

为了进一步锁定,您可以禁用Cache-ControlPHP 路由服务器块中的标头,以确保页面不会被缓存在浏览器中:

location ~ \.php$ {
    more_clear_headers "Cache-Control";
    ...

如果您的客户喜欢摆弄设置,这种方法可以救您一命。

相关内容