Nginx 配置高性能静态网站 - 缓存、Gzip、跨域和防盗链

2024-08-13 07:41:39 浏览数 (2)

概述

本篇博客对配置Nginx静态网站中的缓存、Gzip、跨域和防盗链等四个知识点在之前的生产实践中遇到的问题进行归纳和总结,分享出来,以方便同学们有更好的成长。

Nginx 配置高性能静态网站

缓存

通过配置合理的缓存机制,可以让浏览器访问不同的页面时不需要多次连接网站服务器上,获取这样重复调用的资源,从而减少浏览器等待的时间,提升性能,提升用户体验。

可以使用正数或负数,Expires头部信息的值,将通过当前系统时间加上设定time值来设定,time值还控制Cache-Control的值,负数表示no-cache,正数或0表示max-age=time

代码语言:shell复制
    location ~* .(jpg|jpeg|png|gif)$ {
        expires 30d;
    }

    #expires 30s;   #缓存30秒
    #expires 30m;   #缓存30分钟   
    #expires 2h;    #缓存2小时
    #expires 30d;   #缓存30天
原理解析

原理和步骤:

1、用户首次通过浏览器发送请求到服务端获取数据,客户端是没有对应的缓存,所以需要发送request请求来获取数据;

2、服务端接收到请求后,获取服务端的数据及服务端缓存的允许后,返回200的成功状态码并且在响应头上附上对应资源以及缓存信息;

3、当用户再次访问相同资源的时候,客户端会在浏览器的缓存目录中查找是否存在响应的缓存文件

4、如果没有找到对应的缓存文件,则走(2)步

5、如果有缓存文件,接下来对缓存文件是否过期进行判断,过期的判断标准是(Expires)

6、如果没有过期,则直接从本地缓存中返回数据进行展示

7、如果Expires过期,接下来需要判断缓存文件是否发生过变化,判断的标准有两个,一个是ETag(Entity Tag),一个是Last-Modified

8、判断结果是未发生变化,则服务端返回304,直接从缓存文件中获取数据

9、如果判断是发生了变化,重新从服务端获取数据,并根据缓存协商(服务端所设置的是否需要进行缓存数据的设置)来进行数据缓存。

字段解释

header

说明

Expires

缓存过期的日期和时间

Cache-Control

设置和缓存相关的配置信息

Last-Modified

请求资源最后修改时间

ETag

请求变量的实体标签的当前值,比如文件的MD5值

If-Modified-Since

客户端再次发起请求时,携带上次请求返回的Last-Modified值

If-None-Match

客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值

浏览器缓存过程分析

浏览器第一次向服务器发起该请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存中。

浏览器根据是否需要向服务器重新发起HTTP请求将缓存过程分为两个部分,分别是强制缓存协商缓存

强制缓存:强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。

  • 强制缓存规则:当浏览器向服务器发送请求的时候,服务器会将缓存规则放入HTTP响应的报文的HTTP头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Conctrol的优先级比Expires高。
  • Expires: Expires是HTTP/1.0控制网页缓存的字段,其值为服务器返回该请求的结果缓存的到期时间,即再次发送请求时,如果客户端的时间小于Expires的值时,直接使用缓存结果。到了HTTP/1.1,Expires已经被Cache-Control替代,原因在于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,如果客户端与服务端的时间由于某些原因(时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强制缓存直接失效,那么强制缓存存在的意义就毫无意义。
  • Cache-Control的参数说明和配置

参数

说明

public

所有内容都将被缓存(客户端和代理服务器都可缓存)

private

所有内容只有客户端可以缓存,Cache-Control的默认取值

no-cache

客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定

no-store

所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存

max-age=xxx (xxx is numeric)

缓存内容将在xxx秒后失效

代码语言:shell复制
location ~* .(css|js)$ {
    expires 7d;
    add_header Cache-Control "public";
}

也可以这样配置:

代码语言:shell复制
location ~* .(css|js)$ {
    expires 600;
    add_header Cache-control max-age=800;
}

下面是从浏览器复制出的请求Http参数:

代码语言:shell复制
HTTP/1.1 304 Not Modified
Server: nginx
Date: Sun, 11 Aug 2024 12:46:58 GMT
Last-Modified: Fri, 09 Aug 2024 10:03:08 GMT
Connection: keep-alive
ETag: "66b5e95c-2c7"
Expires: Mon, 12 Aug 2024 12:46:58 GMT
Cache-Control: max-age=86400
Cache-Control: public
Gzip模块

通过配置网站服务器进行输出压缩,可以减少http响应传输的数据量,从而提高网站页面的加载速度。

代码语言:shell复制
location ~ .*.(jpg|gif|png|js)$ {
    gzip on;
    gzip_http_version 1.1;
    gzip_comp_level 2; # 压缩级别,默认1,最高9
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif img/png;
}
跨域和防盗链

跨域和防盗链的配置主要出于安全方面的考虑,允许合法的用户来进行访问。

代码语言:shell复制
server {
    listen 80;
    server_name www.stark.com;

    location / {
        # 设置允许跨域的域,* 表示允许任何域,也可以设置特定的域
        add_header 'Access-Control-Allow-Origin' 'http://stark1.com https://stark2.com';
        # 允许的方法
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        # 允许的头信息字段
        add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type';
        # 缓存时间
        add_header 'Access-Control-Max-Age' 1728000;

        # 预检请求的处理
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }
        # 这里是你的Nginx服务器的其他配置
    }
}

盗链是指本网站的图片等资源链接被使用到了其他非授权的网站页面上。对于被盗链的网站来说,被消耗了大量的带宽和服务器资源,但没产生任何价值。通过配置网站服务器对收到的请求中的Referer进行检查,可以有效避免静态资源被第三方网站盗链。

Http Referer是Http请求头部信息的一部分,当浏览器向网站服务器发送请求的时候,一般会带上Referer,告诉服务器是从哪个页面链接过来的,服务器因此可以获得一些信息用户处理。

代码语言:shell复制
server {
    listen 80;
    server_name yourdomain.com;

    location / {
        root /path/to/your/files;
        valid_referers none blocked server_names *.yourdomain.com;
        if ($invalid_referer) {
            return 403;
        }
    }
}

0 人点赞