前言
参考链接:nginx_百度百科 未安装 Nginx 配置的话请移步至:Nginx的反向代理与负载均衡—配置Nginx
1. 首先需要了解的是浏览器的整个的执行机制
- 浏览器对我们的静态资源,比如说 js css html 图片 字体 等都是有缓存策略的,如果说浏览器自身有缓存,它就会从自己本身的缓存里读了,我们也可以通过网络层类似于我们的服务器包括 Nginx 还有各种各样的静态资源服务器来设置我们的缓存
- 首先是如果本机的浏览器有缓存的话,那么他直接就在这个缓存里就获取到了,然后呈现给用户
- 那么这个缓存还需要查看,如果是在网络上会查看它是否是过期的:
- 如果不是过期的,它也是从本地的缓存中读取之后就可以了;
- 如果是过期的就需要看一下这个资源有没有 Etag 这样的东西,Etag 是浏览器向服务器发送请求时的一个请求报头,服务器那边也会响应这个请求报头,然后两边共同的匹配一下资源是否过期,如果有 Etag 的话,它就会向浏览器注入 If-None-Match (如果没有匹配 — 百度翻译)这样的头。然后向我们的 webserver 发过去,然后服务器那边做一个基础的策略:是否是匹配的 Etag ,如果是匹配的就返回一个 304,如果没有匹配就给 Etag 这个文件一个戳,然后返回 200 更新,这样下次再请求的时候有了这个 Etag 就不会再把整个的资源再重新拉回来了
- 如果没有发现 Etag 的话,在我们服务器还可以设 Expires ,Expires 这个东西就是过期时间,他发现 Last-Modified (最后修改 — 百度翻译)这样一个策略,它会向我们的服务器发送一个 If-Modified-Since (如果更改了 — 百度翻译)就是说上次的修时间,然后和服务器的 Expires 做一个对比,如果发现过期了就返回一个新的,如果是没过期就返回一个 304
- 如果是上面的 Etag 和 Last-Modified 两个值都没有,那么他就会直接向我们的 web服务器发送一个请求,然后是请求响应—缓存协商
- 如果是上面的 Etag 和 Last-Modified 这两个值都进行设置了,那么就是会将两个值都比较,都满足了之后才会最终得到一个响应,没有谁先谁后的问题,那么当我们设置对应的文件的时候,你会发现很多对应的服务器都是同时的对他们进行设置的,就是设置了 Etag 又设置了 Last-Modified ,所以说当你这个文件有对应的修改的时候,你还要及时的去修改这个 Last-Modified 就是里面的一个 Expires 的东西
- Etag 相比于 Expires 有很多优点,它是一个基于文件的一个戳的比较,可以实现一个实时的更新,Expires 这个东西实际上是做不到那种秒秒级别的,它是一个 Unix 的一个时间戳,他做不到那种特别精细的时间的控制
- 现在的话你也可以在 Header 里面设 control ,可以直接重写掉 Expires 这样的东西
- 如果是一个整个的项目,你不是运维工程师的话,你可以跟运维去说:我需要设置这个文件对应的强缓,就比如说:这个文件 30 年不过期,例如 jquery 这种长时间不过期的文件,这个的话一般就用 Expires 的比较多,就是说过期时间设置较长这个就是强缓,那么 Etag 的话一般是针对的我们的业务的文件
#接着下面是将上面所述的整个过程在 Nginx 里面进行演示
###前言
- 你需要知道的是:在任何的其他的服务器里面,它们这个的逻辑、思维是一样的,关键是要去看你是怎么去配置的。
- 操作 Nginx 的基础是你已经在服务器端安装并配置好了,我这里衔接的是 Nginx的反向代理与负载均衡—配置Nginx 这篇文章,这里我选择使用的是 Centos
具体的操作
在本机使用 Cmder 命令行终端通过
ssh
命令远程登录上 Centos 服务器上,温馨提示:这里你有可能会因为服务器的 ssh 服务没有开启又或者是 防火墙未关闭、服务器未开启而导致无法连接,请先在服务器端确保无误之后再进行操作ssh root@192.168.230.129
Enter your password
在命令行中进入 nginx 配置文件的目录
cd /etc/nginx/
查看当前目录下的所有文件
ls
查看 nginx.conf 配置文件的内容
cat nginx.conf
然后再重新打开一个命令行窗口
//先远程登录
ssh root@192.168.230.129
Enter your password
//再进入到 存放 nginx 静态资源的目录
cd /usr/share/nginx/
//查看目录下的所有文件 这里面是有一个存放项目的 html 的文件夹
ls
然后先查看 nginx 状态,如果未启动,先执行启动服务的命令,之后再查看状态是否为 running 启动中
systemctl status nginx
systemctl start nginx
systemctl status nginx
启动之后就可以在浏览器中打开服务器 IP 地址的在 ngnix.conf 文件中配置的 8080 端口了
这里我们对 /usr/share/nginx/ 下的 HTML 文件夹进行一些操作
先查看文件找到 index.html
cd html
ls
编辑 index.html 文件
vi index.html
这里在我执行上面的命令时进行了提示,这里直接回车就可以了
然后就可以看到这个文件的源码了,然后按下键盘上的 i 键进入可编辑状态
下面的 INSERT 表示现在是可编辑状态
修改源码:在源码的 body 里面引入 jquery 文件,这里我直接是有的是 bootcdn 上的资源,再修改文字并增加 utf-8 编码格式
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
退出并保存
//先按键盘上的 ESC 键
//然后再按 shift + :
//之后再输入 wq (wq 是保存并退出 q! 是不保存并退出)
//再回车
之后就可以刷新浏览器查看下修改的是否已成功以及 jquery 是否已经引用上
之后我在第二个命令行窗口中再 html 文件夹的同一级目录下新建一个 images 目录,并将本机桌面的图片复制到服务器上,再在 index.html 中引入
//先查看当前路径
pwd
再在命令行中新开一个窗口,使用
scp
命令将桌面下的 000.jpg 文件复制至服务器的 /usr/share/nginx/html 文件夹下//先进入桌面查看具体路径
cd Desktop
// scp 要复制的文件路径 用户名 @ 服务器IP地址 : 文件路径 要复制到那里的路径名称
scp ./000.jpg root@192.168.230.129:/usr/share/nginx/html
Enter your password
接着回到第二个命令行窗口下查看是否复制成功了
ls
接着在 index.html 中引入上面复制过来的图片
cd ..
cd html
vi index.html
i
//在html 中新增一个 img 标签引入刚才复制的 img 文件
<img src="./000.jpg" >
ESC
shift + :
wq
这个时候在刷新浏览器会发现图片已经引用成功了
这里还可以在 nginx.conf 配置文件中增加图片类型引用时的判断,其他的静态资源也是同样的套路
- 这个设置的意思是:在请求所有的目录的路径中匹配 图片 正则表达式,如果匹配的话就是下面的 第一行是 文件的具体路径;第二行是过期时间 30天
还有一个需要注意的是:再进行验证的时候不能把下图中的这个
Disable cache
勾选上,这个勾选上的话就是禁用缓存了,这里我们实现的是需要缓存的,所以是绝对不能勾选的接着来分析一下请求到的东西
document
- 请求报文中的 Accept-Encoding 这个可以看到是支持 gzip 压缩的
- 返回报文中的 ETag 加了一个戳,这个是 nginx 默认就开启的,如果是想要关闭的话,在 nginx.conf 文件中的
http
对象里加etag: off;
即可,开启就是 on,不加的话默认的就是 on - 可以看到下面请求报文中有一个
If-None-Match
的值也是和上面的 Etag 的值是一样的
jquery
- 因为这这里默认开启了 Etag 所以当你下次刷新的时候,它会跟服务器做对比,如果 Etag 的值是一样的说明没有改变就返回的是 304 ,可以看到下面请求报文中有一个
If-None-Match
的值也是和上面的 Etag 的值是一样的
- 因为这这里默认开启了 Etag 所以当你下次刷新的时候,它会跟服务器做对比,如果 Etag 的值是一样的说明没有改变就返回的是 304 ,可以看到下面请求报文中有一个
- 接下来在第一个命令行窗口中在 nginx.conf 文件中将 gzip 开启,对比一下效果
vi nginx.conf
i
//添加一行代码
gzip on;
ESC
shift + :
wq
之后再重载 nginx
nginx -s reload
再次刷新浏览器,查看
document
- 这个返回的是 304 是因为我们的 index.html 文件没有改变,ETag 的值也没有发生改变,如果 Etag 值是一样的说明没有改变就返回的是 304 ,可以看到下面请求报文中有一个
If-None-Match
的值也是和上面的 Etag 的值是一样的
- 这个返回的是 304 是因为我们的 index.html 文件没有改变,ETag 的值也没有发生改变,如果 Etag 值是一样的说明没有改变就返回的是 304 ,可以看到下面请求报文中有一个
为了看出效果我们在第二个命令行窗口中修改 index.html 文件
vi index.html
i
//如果有一些提示语的话回车一下
//在之前的 "小川" 前面加一个 "孙"
ESC
shift + :
wq
之后再刷新浏览器
这个文字已经相应的更新过来了
也会发现
document
返回的报文中多了一个 gzip 的属性,然后是可以看到下面请求报文中有一个If-None-Match
的值和上面的 Etag 的值已经不一样的,这个的机制是以If-None-Match
后面的戳去匹配 Etag 也就是服务器响应的戳,发现是不一样的就会重新将更新后的资源拿过来 状态码也是 200
再次刷新浏览器会发现,状态码是 304 了,而且 ‘If-None-Match’ 的戳和 Etag 的戳已经变成一样的了
这个走的就是下图所标识的地方
如果是没有这个 Etag ,它会校验
Last-Modified
和If-Modified-Since
的戳是否一样,服务器来返回相应的状态
- 接下来在第一个命令行窗口中在 nginx.conf 文件中增加一个
epirse
,过期时间的属性,对比一下效果vi nginx.conf
i
//编辑文件新增 属性 30d 是 30天
expires 30d;
重载
nginx -s reload
还需要像之前的那样对 index.htmlHTML 文件进行一些修改,这样方便于查看效果
- 在 第二个命令行窗口中进行修改
vi index.html
i
//将 "孙小川" 改为 "xiaochuan"
ESC
shift + :
wq
- 在 第二个命令行窗口中进行修改
这个时候再刷新浏览器查看
- 这个时候会发现返回报文中多了一个 Expires 过期时间的属性,后面的值刚好是今天再加上 30 天之后的具体日期
- 这个时候会发现返回报文中多了一个 Expires 过期时间的属性,后面的值刚好是今天再加上 30 天之后的具体日期
- 还可以在 nginx.conf 文件中加一句话:告诉浏览器不要缓存文件
add_header Cache-Control no-cache;
再重载
nginx -s reload
随便修改一下 index.html 文件
再刷新浏览器,第一次是 200 第二次是 304 ,还有就是服务器返回时也有明确的标识:Cache-Control: no-cache 就是告诉浏览器不要缓存,然后具体的资源文件是像服务器请求的,服务器来决定返回的状态码
总结
- 将上面的东西都尝试的设置一遍之后,那么 Nginx 上比较关键的东西:Gzip 、Etag、 Expires (过期时间)、Cache-Control 这些就都配置好了;
Cache-Control 下面还会有一些非常细致的东西:如果你在 Cache-Control 中配置了更多的过期时间就可以直接把 Expires 直接重写掉了,在一些不支持 HTTP.1 的浏览器里设置 Expires 是没有用的,所以你还是要再设置一个 Cache-Control 百度官网的一个 js 文件的响应头部,有颜色的那些对我们来说都是需要掌握的东西
掌握这个东西之后,对于以后来讲我们就可以跟运维去聊这个东西,比如说:我们的 jquery ,你就可以直接告诉他,我的这个jquery需要在页面上缓存多久多久,这个就可以设置一个 过期时间 Expires 或者是 Cache-Control,我的其他业务文件可能会临时变,所以需要配置 Etag ,这样的话他就会非常清楚的知道要怎样去配置这些相应的文件,当然这个东西具体操作还是运维去做的,我们只是需要知道这些东西是干嘛的就可以了