又到了前端啥都要学系列
Nginx定义 & 优点
Nginx
(engine x) 是一个轻量级、高性能的HTTP、反向代理服务器,同时也是一个通用代理服务器(TCP/UDP/IMAP/POP3/SMTP)
它具有高性能,占用内存少,并发能力强的优点,最大可以支持50000个并发连接数
Nginx的常用命令
安装
当然,在开始使用之前,你需要先下载Nginx
官网链接:http://nginx.org/en/download.html
下载完毕后,解压即可使用,目录是这样的
目录树如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| ├── client_body_temp ├── conf # Nginx所有配置文件的目录 │ ├── fastcgi.conf # fastcgi相关参数的配置文件 │ ├── fastcgi.conf.default # fastcgi.conf的原始备份文件 │ ├── fastcgi_params # fastcgi的参数文件 │ ├── fastcgi_params.default │ ├── koi-utf │ ├── koi-win │ ├── mime.types # 媒体类型 │ ├── mime.types.default │ ├── nginx.conf # Nginx主配置文件 │ ├── nginx.conf.default │ ├── scgi_params # scgi相关参数文件 │ ├── scgi_params.default │ ├── uwsgi_params # uwsgi相关参数文件 │ ├── uwsgi_params.default │ └── win-utf ├── fastcgi_temp # fastcgi临时数据目录 ├── html # Nginx默认站点目录 │ ├── 50x.html # 错误页面优雅替代显示文件,例如当出现502错误时会调用此页面 │ └── index.html # 默认的首页文件 ├── logs # Nginx日志目录 │ ├── access.log # 访问日志文件 │ ├── error.log # 错误日志文件 │ └── nginx.pid # pid文件,Nginx进程启动后,会把所有进程的ID号写到此文件 ├── proxy_temp # 临时目录 ├── sbin # Nginx命令目录 │ └── nginx # Nginx的启动命令 ├── scgi_temp # 临时目录 └── uwsgi_temp # 临时目录
|
常用命令
PS:默认情况下,你需要在目录位置对应的控制台下才能运行这些命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| # 启动 (启动效果可以访问http://localhost:80查看) $ nginx $ start nginx
# 查看版本(-v换成-V可以查看更详细的版本信息) $ nginx -v nginx version: nginx/1.24.0
# 检查配置语法是否正确 $ nginx -t nginx: the configuration file G:\program\nginx-1.24.0/conf/nginx.conf syntax is ok nginx: configuration file G:\program\nginx-1.24.0/conf/nginx.conf test is successful
# 重新载入Nginx # 当配置信息修改时,使用这个命令重新加载nginx配置 $ nginx -s reload
# 停止nginx # PS:-s是代表向nginx进程发送通知的意思 $ nginx -s stop $ nginx -s quit
# 查看全部命令 $ nginx -h nginx version: nginx/1.24.0 Usage: nginx [-?hvVtTq] [-s signal] [-p prefix] [-e filename] [-c filename] [-g directives] Options: -?,-h : this help -v : show version and exit -V : show version and configure options then exit -t : test configuration and exit -T : test configuration, dump it and exit -q : suppress non-error messages during configuration testing -s signal : send signal to a master process: stop, quit, reopen, reload -p prefix : set prefix path (default: NONE) -e filename : set error log file (default: logs/error.log) -c filename : set configuration file (default: conf/nginx.conf) -g directives : set global directives out of configuration file
|
Nginx配置
这里循序渐进地对Nginx
配置做一些简单的介绍
从默认的Nginx文件开始
nginx的默认配置文件nginx.conf在安装目录conf文件夹下
在移除所有Nginx注释后,我们可以得到以下配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| worker_processes 1;
events { worker_connections 1024; }
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
|
其中,每个块的作用如下,这里我们重点关注server
和location
块即可
- 全局块:nginx全局块是指nginx配置文件中的最外层块,它可以包含多个指令和其他块,用于定义全局的配置和行为,
- events块:主要用于配置事件驱动模型和连接数限制。
- http块:用于定义HTTP全局配置。处理代理,缓存,日志定义等绝大多数功能和第三方模块的配置,比如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
- server块:配置虚拟主机的相关参数。
- location块:定义一个URI或者URI模式对应的请求处理规则。
location块的处理规则
Location
的具体语法为
1
| location [ = | ~ | ~* | ^~ ] uri { ... }
|
例子如下
PS:不知道为什么,匹配大小写的设置无法生效,可能是window的nginx有问题?或者是nginx新版本有什么问题…以后再看看吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| server { listen 9998; server_name localhost;
location = /getUser { add_header Content-Type "application/json"; return 200 "{id: 1, age: 16}"; }
location ~ ^/getData$ { add_header Content-Type "application/json"; return 200 "{id: 2, age: 16}"; }
location ~* ^/list$ { add_header Content-Type "application/json"; return 200 "[1,2,3]"; }
location ^~ /img/ { root static/; index index.html; } }
server { listen 9997; server_name localhost; location /css { root static/; index index.html; } location / { add_header Content-Type "text/plain"; return 200 "Hello World"; } }
|
相对简单,用到时再查就完事
这里值的顺便一提的是,如果有多个location
规则可以命中,那么会遵循一定的优先级配置来进行返回。
- 检查使用前缀字符串(也就是通用匹配开头)的 locations,在使用前缀字符串的 locations 中选择最长匹配的,并将结果进行储存
- 如果匹配到符合带有
=
修饰符的 URI,则立刻停止匹配
- 如果符合带有
^~
修饰符的 URI,则也立刻停止匹配。
- 然后按照定义文件的顺序,检查正则表达式(也就是前面带
~*
和 ~
修饰符的),匹配到就停止
- 当正则表达式匹配不到的时候,使用之前储存的前缀字符串
一些简单的Nginx模板
加载自定义配置
这里我们用include
指令加载nginx
的相关配置
1 2 3 4
| http { include mime.types; include config/*.conf; }
|
启动一个静态网站服务
在nginx/conf/config
目录下新建一个static-server.conf
文件,然后加上以下配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| server { listen 9999; server_name localhost;
gzip on; gzip_min_length 1k; gzip_types application/javascript; gzip_static on;
location / { root static/; index index.html; } }
|
然后,在/static
目录下,加上一些文件
调用nginx -s reload
重启配置后,就可以通过访问localhost:9999
查看效果了
单页应用路由处理
总所周知,如果你的路由使用了history
模式,那么在访问localhost:8080/about
这种链接时,会返回404
原因是nginx会把这个连接当成一个文件去处理(你可以在dist目录下加一个about文件来验证),而nginx找不到这个文件,所以就会返回404
1 2 3 4 5 6 7 8 9 10 11
| server { listen 9996; server_name localhost;
location / { root dist/; index index.html; try_files $uri $uri/ /index.html; } }
|
我们仅需在静态网站的基础上,添加一行try_files $uri $uri/ /index.html
配置即可,这样我们就可以将路由请求重定向回index.html
了(但注意,不要在目录下存放和路由同名的文件,不然的话,就会访问那个同名的文件)。
开启防盗链
只要在nginx中加入以下的配置即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| server { listen 9999; server_name localhost;
location ~* .*\.(gif|jpg|png)$ { root static/; valid_referers localhost; if ($invalid_referer) { rewrite ^/ https://s2.loli.net/2023/04/25/HyDgp25ZsVxwJ83.png; break; } } }
|
负载均衡
平均将请求转发到两台服务器上
1 2 3 4 5 6 7 8 9 10 11 12
| upstream webapp { server localhost:9996 weight=1; server localhost:9999 weight=1; random two least_conn; }
server { listen 9995; location / { proxy_pass http://webapp; } }
|
跨域
跨域的配置非常简单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| server { listen 8070; location / { add_header 'Access-Control-Allow-Origin' * always; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT'; add_header 'Access-Control-Allow-Headers' *; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } proxy_pass https://server.com; } }
|
请求的时候使用以下代码
1 2 3 4 5 6 7 8
| let baseUrl = IsDev ? "http://localhost:8070/" : `https://server.com`; let instance = axios.createInstance({ baseUrl: baseUrl }); (async function () { let data = await instance.get("/data"); console.log('data', data); })()
|
参考
前端仔也需要懂的nginx内容:https://juejin.cn/post/7007346707767754765
Nginx location匹配规则:https://www.cnblogs.com/woshimrf/p/nginx-config-location.html
Nginx配置文件介绍:https://zhuanlan.zhihu.com/p/396032376
nginx.conf配置文件详解:https://juejin.cn/post/6844903741678698510
nginx反向代理解决跨域问题:https://juejin.cn/post/6995374680114741279
nginx一网打尽:https://juejin.cn/post/7112826654291918855#heading-13