介绍
网站加载速度越快,访问者就越有可能留下来。当网站充满了由在后台加载的脚本运行的图像和交互式内容时,打开网站不是一个简单的任务。它包括从服务器一个一个请求许多不同的文件。最小化这些请求的数量是加快您的网站的一种方式。 这可以以许多方式来完成,但是,采取更重要的步骤之一是配置 浏览器缓存 。这告诉浏览器,下载一次的文件可以从本地副本中重用,而不是一次又一次地请求服务器。为此,必须引入新的HTTP响应标头告诉浏览器如何行为。 这是Nginx的header模块发挥作用。此模块可用于向响应中添加任何任意头,但其主要作用是正确设置缓存头。在本教程中,我们将看看如何使用Nginx的header模块来实现浏览器缓存。先决条件
要遵循本教程,您需要:- 一个Ubuntu的16.04服务器设置与初始服务器设置教程 ,包括Sudo非root用户。
- 遵循您的服务器上安装的Nginx 如何在Ubuntu 16.04安装教程Nginx。
第1步 - 创建测试文件
在这一步中,我们将在默认的Nginx目录中创建几个测试文件。我们稍后将使用这些文件来检查Nginx的默认行为,然后测试浏览器缓存是否正常。 要做出关于通过网络提供什么类型的文件的决定,Nginx不分析文件内容;这将是极其缓慢。相反,它只是查找文件扩展名来确定该文件的 MIME类型 ,表示该文件的目的。 由于这种行为,我们的测试文件的内容是不相关的。通过适当地命名文件,我们可以欺骗Nginx认为,例如,一个完全空的文件是一个图像,另一个是一个样式表。 创建一个文件名为test.html
使用Nginx的目录的默认
truncate
。此扩展表示它是一个HTML页面。
sudo truncate -s 1k /var/www/html/test.html
让我们创建以相同的方式多几个测试文件:一个
jpg
的图像文件,人们
css
样式表,和一个
js
JavaScript文件。
sudo truncate -s 1k /var/www/html/test.jpg
sudo truncate -s 1k /var/www/html/test.css
sudo truncate -s 1k /var/www/html/test.js
下一步是检查Nginx在新安装时发送缓存控制头的方式与我们刚刚创建的文件的行为。
第2步 - 检查默认行为
默认情况下,所有文件都将具有相同的默认缓存行为。为了探索这一点,我们将使用我们在第1步中创建的HTML文件,但是您可以使用任何示例文件运行这些测试。 所以,让我们检查test.html
获送达有关浏览器应该多长时间缓存响应的任何信息。以下命令从我们的本地Nginx服务器请求一个文件,并显示响应头。
curl -I http://localhost/test.html
您应该会看到几个HTTP响应标头:
Output: Nginx response headersHTTP/1.1 200 OK
Server: nginx/1.10.0 (Ubuntu)
Date: Sat, 10 Sep 2016 13:12:26 GMT
Content-Type: text/html
Content-Length: 1024
Last-Modified: Sat, 10 Sep 2016 13:11:33 GMT
Connection: keep-alive
ETag: "57d40685-400"
Accept-Ranges: bytes
在倒数第二行,你能看到
ETag
头,包含所请求的文件的这个特定版本的唯一标识符。 如果执行前面的
curl
反复命令,你会看到完全一样
ETag
值。 当使用网络浏览器,所述
ETag
值被存储,并与发送回服务器
If-None-Match
时,浏览器想要再次请求相同的文件请求头-例如,刷新页面时。 我们可以在命令行上使用以下命令来模拟它。请确保您更改
ETag
此命令值以匹配
ETag
在你以前的产值。
curl -I -H 'If-None-Match: "57d40685-400"' http://localhost/test.html
现在的响应会有所不同:
Output: Nginx response headersHTTP/1.1 304 Not Modified
Server: nginx/1.10.0 (Ubuntu)
Date: Sat, 10 Sep 2016 13:20:31 GMT
Last-Modified: Sat, 10 Sep 2016 13:11:33 GMT
Connection: keep-alive
ETag: "57d40685-400"
这一次,Nginx的将与
304未修改响应。它不会再次通过网络发送文件;相反,它会告诉浏览器它可以重用已经本地下载的文件。 这是有用的,因为它减少了网络流量,但它不够好,以达到良好的缓存性能。这个问题
ETag
是该浏览器
总是发送到服务器询问是否可以重新使用它的高速缓存文件的请求。即使服务器用304响应而不是再次发送文件,但是仍然需要时间来进行请求和接收响应。 在下一步中,我们将使用headers模块附加缓存控制信息。这将使浏览器在本地缓存一些文件,而不明确询问服务器是否罚款这样做。
第3步 - 配置缓存控制和到期标头
除了ETag
文件验证头,有两个缓存控制响应头:
Cache-Control
和
Expires
。
Cache-Control
是较新的版本,其中有更多的选择比
Expires
,一般是比较有用的,如果你想在你的缓存更精细的控制行为。 如果这些头设置,他们可以告诉浏览器,请求的文件可以在本地保存一定的时间(包括永远),而不需要再次请求。如果没有设置标题,浏览器总是从服务器请求的文件,希望无论是
200 OK或
304未修改响应。 我们可以使用header模块来设置这些HTTP头。header模块是一个核心的Nginx模块,这意味着它不需要单独安装使用。 要添加header模块,打开默认的Nginx的配置文件
nano
或您喜爱的文本编辑器。
sudo nano /etc/nginx/sites-available/default
找到
server
配置块,它看起来像这样:
/ etc / nginx / sites-available / default
. . .
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
. . .
这里补充以下两个新的部分:一个前
server
模块,定义多久缓存不同的文件类型,和一个里面,适当地设置缓存头。
修改/ etc / nginx / sites-available / default
. . .
# Default server configuration
#
# Expires map
map $sent_http_content_type $expires {
default off;
text/html epoch;
text/css max;
application/javascript max;
~image/ max;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
expires $expires;
. . .
在之前的部分
server
模块是一个新
map
模块定义文件类型多久了此类文件应该被缓存之间的映射。 我们在此地图中使用了几种不同的设置:
- 默认值被设置为
off
,这将不添加任何缓存控制头。这是一个安全的赌注内容我们没有特定的要求如何缓存应该工作。 - 对于
text/html
,我们的值设置为epoch
。这是一个特殊的值,明确地导致没有缓存,这迫使浏览器总是询问网站本身是否是最新的。 - 对于
text/css
和application/javascript
,这是样式表和JavaScript文件,我们将该值设置为max
。这意味着浏览器将尽可能高速缓存这些文件,减少了大量的请求,因为通常有很多这些文件。 - 最后一项设置是
~image/
,这是一个正则表达式将匹配包含所有文件类型image/
在他们的MIME类型名称(如image/jpg
和image/png
)。 如样式表,经常有上可以安全缓存网站大量的图片,所以我们将其设置为max
为好。
expires
指令(header模块的一部分)设置缓存控制头。 它使用从值
$expires
的地图变量集。这样,生成的头将根据文件类型而有所不同。 保存并关闭文件退出。 要启用新配置,请重新启动Nginx。
sudo systemctl restart nginx
接下来,让我们确保我们的新配置工作。
第4步 - 测试浏览器缓存
对测试HTML文件执行与之前相同的请求。curl -I http://localhost/test.html
这个时候的响应会不同。您应该会看到两个额外的HTTP响应标头:
Nginx响应头
HTTP/1.1 200 OK
Server: nginx/1.10.0 (Ubuntu)
Date: Sat, 10 Sep 2016 13:48:53 GMT
Content-Type: text/html
Content-Length: 1024
Last-Modified: Sat, 10 Sep 2016 13:11:33 GMT
Connection: keep-alive
ETag: "57d40685-400"
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Cache-Control: no-cache
Accept-Ranges: bytes
在
Expires
标题显示在过去的日期和
Cache-Control
设置与
no-cache
,它告诉浏览器总是问该服务器是否有该文件的较新版本(使用
ETag
头,像以前一样)。 您将看到与测试图像文件的差异响应。
curl -I https://www.youcl.com/uploadshttp://localhost/test.jpg
Nginx响应头
HTTP/1.1 200 OK
Server: nginx/1.10.0 (Ubuntu)
Date: Sat, 10 Sep 2016 13:50:41 GMT
Content-Type: image/jpeg
Content-Length: 1024
Last-Modified: Sat, 10 Sep 2016 13:11:36 GMT
Connection: keep-alive
ETag: "57d40688-400"
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
在这种情况下,
Expires
显示在遥远的未来日期,
Cache-Control
含有
max-age
信息,它告诉浏览器多久可以在几秒钟内缓存文件。这告诉浏览器缓存下载的图像尽可能长的时间,所以任何后续出现的此图像将使用本地缓存,而不是发送请求到服务器。 结果应该是两个类似的
test.js
和
test.css
,如JavaScript和样式表文件与设置缓存头了。 这意味着缓存控制头已经正确配置,您的网站将受益于浏览器缓存的性能增益和更少的服务器请求。您应该根据您网站的内容自定义缓存设置,但本文中的默认值是一个合理的起始点。