如何在 CentOS 8 上使用 Nginx 的 header 模块实现浏览器缓存

作者选择了 COVID-19 救援基金作为 Write for Donations计划的一部分接受捐款。

介绍

网站加载的速度越快,访问者越有可能留下来. 当网站充满图像和交互式内容,由在背景下加载的脚本运行时,打开网站并不是一个简单的任务。

改善网站性能的一种方法是 browser caching. 浏览器缓存告诉浏览器它可以重复使用下载文件的本地版本,而不是要求服务器一次又一次地为它们提供服务。

Nginx 的标题模块可以帮助您实现浏览器缓存. 您可以使用此模块将任意标题添加到响应中,但其主要作用是正确设置缓存标题。

前提条件

要遵循本教程,您将需要:

步骤 1 - 创建测试文件

在此步骤中,我们将在默认的 Nginx 目录中创建多个测试文件,然后使用这些文件来检查 Nginx 的默认行为,然后测试浏览器缓存是否有效。

要推断在网络上提供什么类型的文件, Nginx 不会分析文件内容;这将是非常慢的;相反,它会查看文件扩展,以确定文件的 _MIME 类型,这表示其目的。

由于这种行为,我们的测试文件的内容是无关紧要的. 通过正确命名文件,我们可以欺骗 Nginx 认为,例如,一个完全空的文件是一个图像,另一个是风格表。

在默认的 Nginx 目录中使用truncate创建名为test.html的文件,此扩展表示它是一个 HTML 页面:

1sudo truncate -s 1k /usr/share/nginx/html/test.html

让我们以同样的方式创建几个测试文件:一个jpg图像文件,一个css样式表和一个jsJavaScript文件:

1sudo truncate -s 1k /usr/share/nginx/html/test.jpg
2sudo truncate -s 1k /usr/share/nginx/html/test.css
3sudo truncate -s 1k /usr/share/nginx/html/test.js

下一步是检查 Nginx 如何在新安装中发送缓存控制标题,以及我们刚刚创建的文件。

步骤2 - 检查默认行为

默认情况下,所有文件将具有相同的默认缓存行为. 为了探索这一点,我们将使用我们在步骤 1 中创建的HTML文件,但您可以运行这些测试与任何示例文件。

所以,让我们检查一下,是否有关于浏览器应该缓存答案多长时间的任何信息。下面的命令要求我们本地的 Nginx 服务器的文件,并显示响应标题:

1curl -I http://localhost/test.html

您应该看到几个HTTP响应标题:

 1[secondary_label Output: Nginx response headers]
 2HTTP/1.1 200 OK
 3Server: nginx/1.14.1
 4Date: Thu, 04 Feb 2021 18:23:09 GMT
 5Content-Type: text/html
 6Content-Length: 1024
 7Last-Modified: Thu, 04 Feb 2021 18:22:39 GMT
 8Connection: keep-alive
 9ETag: "601c3b6f-400"
10Accept-Ranges: bytes

在第二行到最后一行中,你会发现ETag标题,其中包含这个特定修订所请求的文件的唯一标识符. 如果你重复执行以前的curl命令,你会找到相同的ETag值。

在使用网页浏览器时,存储ETag值,并在浏览器想要再次请求相同的文件时(例如,当更新页面时)将其发送回服务器。

我们可以通过以下命令在命令行上模拟这一点,请确保您更改此命令中的ETag值以匹配您以前的输出中的ETag值:

1curl -I -H 'If-None-Match: "601c3b6f-400"' http://localhost/test.html

现在的答案将是不同的:

1[secondary_label Output: Nginx response headers]
2HTTP/1.1 304 Not Modified
3Server: nginx/1.14.1
4Date: Thu, 04 Feb 2021 18:24:05 GMT
5Last-Modified: Thu, 04 Feb 2021 18:22:39 GMT
6Connection: keep-alive
7ETag: "601c3b6f-400"

这一次, Nginx 将以 304 Not Modified 响应,不会再通过网络发送该文件;相反,它会告诉浏览器,它可以重复使用已经本地下载的文件。

这是有用的,因为它减少网络流量,但它不够好,以实现良好的缓存性能。与ETag的问题是,浏览器总是向服务器发送请求,询问它是否可以重复使用其缓存文件。

在下一步,我们将使用标题模块添加缓存控制信息,这将使浏览器在本地缓存某些文件,而不明确地询问服务器是否可以这样做。

步骤 3 – 配置缓存控制和到期标题

除了「ETag」文件验证标题外,还有两个缓存控制响应标题:「Cache-Control」和「Expires」。

如果这些标题被设置,它们可以告诉浏览器,请求的文件可以被保留在本地一段时间(包括永远)而不会再次要求它。

我们可以使用头部模块来设置这些 HTTP 头部模块,头部模块是核心的 Nginx 模块,这意味着它不需要单独安装才能使用。

若要添加标题模块,请在vi中打开默认服务器封锁 Nginx 配置文件(以下是对vi的简要介绍(https://andsky.com/tech/tutorials/installing-and-using-the-vim-text-editor-on-a-cloud-server#modal-editing))或您最喜欢的文本编辑器:

1sudo vi /etc/nginx/nginx.conf

查找服务器配置块:

1[label /etc/nginx/nginx.conf]
2. . .
3server {
4    listen 80 default_server;
5    listen [::]:80 default_server;
6    server_name _;
7    root         /usr/share/nginx/html;
8. . .

这里添加以下两个新部分:一个在服务器块前,以定义如何缓存不同类型的文件,一个在其内部,以适当设置缓存标题:

 1[label Modified /etc/nginx/nginx.conf]
 2. . .
 3# Expires map
 4map $sent_http_content_type $expires {
 5    default off;
 6    text/html epoch;
 7    text/css max;
 8    application/javascript max;
 9    ~image/                    max;
10    ~font/                     max;
11}
12
13server {
14    listen 80 default_server;
15    listen [::]:80 default_server;
16    server_name _;
17    root         /usr/share/nginx/html;
18
19    expires $expires;
20. . .

服务器块前的部分是一个新的地图块,它定义了文件类型之间的映射以及该类型的文件应该缓存多长时间。

我们在这个地图中使用了几个不同的设置:

  • 默认值为关闭,不会添加任何缓存控制标题。 这是一个安全的赌注内容,我们对缓存应该如何工作没有特别的要求. *对于text/html,我们将该值设置为epoch 这是一个特殊的值,这意味着浏览器将尽可能长时间缓存这些文件,迫使浏览器始终询问网站本身是否更新 *对于text/cssapplication/javascript,这些是风格表和JavaScript文件,我们将该值设置为max。 这意味着浏览器将尽可能长时间缓存这些文件,大大减少请求的数量,通常有许多这些文件 *。

<$>[注] 注: 这些只是网站上使用的最常见的 _MIME 类型的一些例子,您可以在 共同的 MIME 类型网站上熟悉这些类型的更广泛的列表,并在地图中添加其他您可能发现有用的类型。

在服务器块内,到期指令(标题模块的一部分)设置了缓存控制标题,它使用地图中的$ expires变量集中的值。

保存并关闭文件以退出。

要启用新的配置,请重新启动 Nginx:

1sudo systemctl restart nginx

接下来,让我们确保我们的新配置工作。

步骤 4 – 测试浏览器缓存

执行与之前的测试 HTML 文件相同的请求:

1curl -I http://localhost/test.html

这一次,答案将不同,您将看到两个额外的 HTTP 响应标题:

 1[label Nginx response headers]
 2HTTP/1.1 200 OK
 3Server: nginx/1.14.1
 4Date: Thu, 04 Feb 2021 18:28:19 GMT
 5Content-Type: text/html
 6Content-Length: 1024
 7Last-Modified: Thu, 04 Feb 2021 18:22:39 GMT
 8Connection: keep-alive
 9ETag: "601c3b6f-400"
10Expires: Thu, 01 Jan 1970 00:00:01 GMT
11Cache-Control: no-cache
12Accept-Ranges: bytes

Expires标题显示了过去的日期,而Cache-Control设置为no-cache,这告诉浏览器始终询问服务器是否有更新的文件版本(使用ETag标题,就像以前一样)。

您将在测试图像文件的响应中找到差异。

1curl -I http://localhost/test.jpg

注意新产量:

 1[label Nginx response headers]
 2HTTP/1.1 200 OK
 3Server: nginx/1.14.1
 4Date: Thu, 04 Feb 2021 18:29:05 GMT
 5Content-Type: image/jpeg
 6Content-Length: 1024
 7Last-Modified: Thu, 04 Feb 2021 18:22:42 GMT
 8Connection: keep-alive
 9ETag: "601c3b72-400"
10Expires: Thu, 31 Dec 2037 23:55:55 GMT
11Cache-Control: max-age=315360000
12Accept-Ranges: bytes

在这种情况下,‘Expires’显示在遥远的未来的日期,而‘Cache-Control’包含‘max-age’信息,这告诉浏览器可以在几秒内缓存文件的时间。

结果应该对test.jstest.css都相似,因为 JavaScript 和风格表文件都设有缓存标题。

这意味着缓存控制标题已正确配置,您的网站将受益于性能提高和由于浏览器缓存而减少的服务器请求。

结论

标题模块可以用来添加任何任意标题来响应,但正确设置缓存控制标题是其最有用的应用程序之一。它提高了网站用户的性能,特别是在具有较高的延迟的网络上,如移动运营商网络上。

您可以找到有关标题模块的更多详细信息 在 Nginx 的官方标题模块文件中

Published At
Categories with 技术
comments powered by Disqus