首页
统计
关于
正则表达式手册
Search
1
React中编写css的几种方式
48 阅读
2
rollup.js的个人理解
41 阅读
3
【整理】Nginx基础知识
37 阅读
4
前端工程化的思考
36 阅读
5
package.json的配置参考
35 阅读
默认分类
服务器端
前端工程化
react
vue
nodejs
js+
html&css
问题集录
临时
dylin
gu
登录
/
注册
Search
标签搜索
问题
前端工程化
基础知识
css
数据库
docker
nginx
rollup.js
react
golang
js
性能优化
js基础
dylin
累计撰写
21
篇文章
累计收到
1
条评论
首页
栏目
默认分类
服务器端
前端工程化
react
vue
nodejs
js+
html&css
问题集录
临时
dylin
gu
页面
统计
关于
正则表达式手册
搜索到
1
篇与
的结果
2023-12-12
【整理】Nginx基础知识
Nginx相关知识Nginx是在前端服务部署时是很重要的一部分,也是部署的基础,学会了通过Nginx部署前端资源,才能继续后续的一系列进阶。一、了解一点简单的Nginx知识本节内容作为基础知识,如果熟悉Nginx可以略过,如果不熟悉可以实际操作一下。现在服务器安装Nginx很简单,一般只需要两行命令即可,安装完成后,启动服务。 # 安装nginx yum install -y nginx # 启动nginx systemctl start nginx # 查看nginx运行状态 systemctl status nginx当我们看到下图,说明你的Nginx运行正常,此时Nginx会启动服务,默认80端口。此时如果我们的服务器外网防火墙 80端口开启,那么访问外网IP,就能看到Nginx启动的服务Nginx的配置文件,一般位于 /etc/nginx目录下,具体内容如下:我们基本只需要关注文件 nginx.conf和 conf.d目录,下面是一份 nginx.conf配置文件,不懂也不要怕,基本都不需要改动,默认80服务已经开启了。 user nginx; # nginx进行运行的用户 error_log /var/log/nginx/error.log; # 错误日志 http { log_format main ...; # nginx日志格式 access_log /var/log/nginx/access.log main; # 日志位置 # 引入的nginx配置文件,可以将server放在该目录下,方便管理 include /etc/nginx/conf.d/*.conf; # 一个nginx服务一个server server { listen 80; # 服务启动的端口 server_name _; # 服务域名或IP root /usr/share/nginx/html; # 服务指向的文件地址 error_page 404 /404.html; # 找不到资源重定向到404页面 location = /40x.html {}; error_page 500 502 503 504 /50x.html; # 系统错误重定向50x页面 location = /50x.html {}; } # server { # listen 443; # 支持https协议 # server_name _; # root /usr/share/nginx/html; # ... # } }我们可以看到该文件分成了多层第一层:user、error_log、http第二层:log_format、access_log、include、server在http下可以有多个 Server,启动多个服务,但如果都写在一个文件里面,文件就越来越大了,那么为了便于管理多个服务,我们要对 nginx.conf进行拆分。conf.d目录下一般是空的,我们新建文件 web.conf或者任意命名的以.conf结尾的文件即可被Nginx使用,内容为: server { listen 80; server_name _; root /usr/share/nginx/html; error_page 404 /404.html; location = /40x.html {}; error_page 500 502 503 504 /50x.html; location = /50x.html {}; }由于这里使用了80端口,之前nginx.conf文件server中listen为80的可以删除了。此时nginx.conf中的文件内容为: user nginx; # nginx进行运行的用户 error_log /var/log/nginx/error.log; # 错误日志 http { log_format main ...; # nginx日志格式 access_log /var/log/nginx/access.log main; # 日志位置 # 引入的nginx配置文件,可以将server放在该目录下,方便管理 include /etc/nginx/conf.d/*.conf; }include /etc/nginx/conf.d/*.conf; 我们看到这一行语句发现,include帮助我们引用conf.d下以.conf结尾的配置文件。完成后执行nginx指令 # 检查nginx配置文件是否正确,如果错误会提示具体的错误信息 nginx -t # 重新启动nginx服务 nginx -s reload观察日志,此时发现Nginx就重新启动了,读取的是新的配置文件。其他操作nginx的指令 nginx -s stop nginx -s start二、启动一个简单的Nginx服务一台服务器或PC,安装并启动Nginx服务/data/web两个html文件 index.html, about.html1、index.html或 about.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>nginx</title> </head> <body> 通过nginx部署的第一个服务 </body> </html>2、修改 /etc/nginx/conf.d/web.conf server { listen 80; server_name localhost; root /data/web; index index.html; }执行 nginx -t确认配置文件修改没问题,再执行 nginx -s reload重启Nginx,此时我们访问外网IP(默认80端口,下面默认都是访问80端口),可以看到这样我们的静态资源文件就部署好了,通过url访问资源:http://xxxx/index.htmlhttp://xxxx/about.html三、部署单页面应用我们快速创建一个CRA单页面应用,修改App.js文件,这里使用 react-router-dom@61、Hash模式 import { HashRouter, Routes, Route, Link } from "react-router-dom"; import './App.css'; function App() { return ( <div className="App"> <HashRouter basename="/"> <div style={{marginBottom: 20}}> <Link style={{marginRight: 20}} to="/">Home</Link> <Link to="/about">About</Link> </div> <Routes> <Route path="/" element={<div>home</div>}></Route> <Route path="/about" element={<div>about</div>} /> </Routes> </HashRouter> </div> ); } export default App;我们执行 yarn build,然后将 build目录下的文件迁移到 /data/web下,再访问服务器IP,发现访问正常,路由切换也没有问题,即部署成功。2、History模式 import { BrowserRouter, ... } from "react-router-dom";将Hash模式中的代码修改为BrowserRouter,运行本地项目,路由切换正常,该路由是History模式同样执行 yarn build生成 build目录,将该目录下的文件迁移到上一步服务器的目录/data/web下,然后访问外网IP,发现渲染效果和上图一样,但是当我们点击About页面,然后刷新浏览器发现,出现了404。先说解决办法,然后解释下原因,修改Nginx配置 web.conf增加一行try_files配置,当请求的地址找不到时,重新指向index.html文件 server { listen 80; server_name localhost; root /data/www/; location / { try_files $uri $uri/ /index.html; index index.html; } }重启nginx nginx -t、nginx -s reload 再次刷新页面,发现页面访问正常了,切换也没有问题。3、为什么hash模式不会出现404,而history模式会出现404?了解下这两种模式的区别就知道答案了1)Hash模式在hash路由模式下,URL中的Hash值(#后面的部分)用来表示应用的状态或路由信息。当用户切换路由时,只有Hash部分发生变化,并没有向服务器发出请求,就做到了浏览器对于页面路由的管理。Hash模式下,URL和路由路径由#号分隔:http://example.com/#/about?query=abc当 #后面的路径发生变化时,会触发浏览器的hashchange事件,通过hashchange事件监听到路由路径的变化,从而导航到不同的路由页面。Hash模式 #后面的路径并不会作为URL出现在网络请求中。例如对于输入的example.com/#/about^[1]^ ,实际上请求的URL是example.com/^[2]^ ,所以不管输入的Hash路由路径是什么,实际网络请求的都是主域名或 IP:Port2)History模式History路由模式下,调用浏览器HTML5中 historyAPI来管理导航。URL和路径是连接在一起的,路由的路径包含在请求的URL里面,路由路径作为URL的一部分一起发送。History模式下,URL路由格式为:http://example.com/about&query=abc当我们向服务器发出请求时,服务器会请求对应的路径的资源综上,当我们打开入口文件index.html的路径时,切换url此时是本地路由,访问正常,但是当我们处于非入口页面时,刷新浏览器,此时发出请求,由于服务器就找不到资源路径了,变成了404。而对于Hash模式来说,总是请求的根路径,所以不会出现这种情况。四、配置反向代理、负载均衡1、反向代理反向代理的用途很多,这里我们看一个常用的,代理请求的接口。我们在发布时前端的域名和后端api服务的域名经常不一致,此时就可以使用Nginx配置反向代理来解决这个问题。 server { location /api { proxy_pass http://backend1.example.com; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }代理的时候要注意添加必要的参数,帮助后端获取一些客户端的请求数据proxy_set_header Host $host; :客户端请求的主机名(Host),不加的话,后端无法获取主机名信息proxy_set_header X-Real-IP $remote_addr;:用户的真实IP(X-Real-IP),如果不设置,后端只能拿到代理服务器的IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;代理链路,如果用户中间经过了多个代理服务器,如果不加这个参数,那么后端服务将无法获取用户的真实来源2、负载均衡Nginx可以作为负载均衡服务器使用,通过配置upstream来分发流量,同时可以配置一些参数:weight:分发权重ip_hash:配置始终将ip的请求始终转发到同一台后端服务器。max_fails: 将某个后台服务标记为不可用之前,允许请求失败的次数backup:标记当前服务为备用服务down:暂时不可用 upstream api { ip_hash; server backend1.example.com; server backend2.example.com; # server backend1.example.com weight=5; } server { location /api { proxy_pass http://api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }五、配置nginx日志Nginx日志也是很重要的一个内容,在我们请求资源出现问题时,要排查请求的资源是否到达Nginx,而且请求日志可以记录很多有用的信息。 log_format gzip '$remote_addr - $remote_user [$time_local] ' : '"$request" $status $bytes_sent ' : '"$http_referer" "$http_user_agent" "$gzip_ratio"'; access_log /var/logs/nginx-access.log gzip buffer=32k;nginx日志主要涉及 access_log,log_formatlog_format: 日志格式,通过nginx内置的变量来读取和排列,通常默认即可access_log: 日志输出的地址、是否压缩、buffer是否当日志大于32k后吸入磁盘六、其他常用配置1、配置Gzip压缩作为前端性能优化的一种方式,Gzip是简单且有效的,尽管目前前端对于静态资源会进行压缩,但Gzip依然可以在网络传输过程中对文件进行压缩下面这些字段可以放在 http、server、location指令模块 http { # 开启关闭 gzip on; # 压缩的文件类型 gzip_types text/plain text/css application/javascript; # 过小的文件没必要压缩 gzip_min_length 1000; # 单位Byte gzip_comp_level 5; # 压缩比,默认1,范围时1-9,值越大压缩比最大,但处理最慢,所以设置5左右比较合理。 }2、配置请求头允许客户端请求在http请求中添加以下划线格式命名的参数该字段可以放在 http指令模块 http { underscores_in_headers on; } ``` **允许客户端上传文件最大不超过1M,在开发上传接口时一定要注意,否则导致上传失败** 该字段可以放在`http、server、location`指令模块 http { client_max_body_size 1m; } ### 3、浏览器缓存配置 **缓存也是前端优化的一个重点,合理的缓存可以提高用户访问速度** 该字段可以放在`http、server、location`指令模块 配置浏览器缓存的有三个地方 #### 1)后端服务,配置请求头 后端根据语言不同,配置关键字段即可 #### 2)代理服务器(Nginx)配置缓存请求头 location /static { # /static匹配到的资源有效期设置为1d; expires 1d; # /设置资源有效期为一周; # expires max-age=604800; # 设置浏览器可以被缓存,设置7天后资源过期 add_header Cache-Control "public, max-age=604800"; # 阻止浏览器缓存动态内容 # add_header Cache-Control "no-cache, no-store, must-revalidate"; # 禁用浏览器缓存 # add_header Cache-Control "no-store, private, max-age=0";} 我们发现响应头的过期时间更新了  #### 3)在前端资源中通过meta声明缓存信息 <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"><meta http-equiv="Expires" content="0"> ### 4、跨域处理 > 通过反向代理,已经处理了请求域名和端口不一致的跨域问题,但有局限性。Nginx有专门方法配置请求资源的跨域 该字段可以放在 `server、location`指令模块,通过配置头部字段,做跨域处理 server {location / { # 允许所有来源的跨域请求 add_header Access-Control-Allow-Origin *; # 允许特定的HTTP方法(GET、POST等) add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE"; # 允许特定的HTTP请求头字段 add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"; # 响应预检请求的最大时间 add_header Access-Control-Max-Age 3600; # 允许携带身份凭证(如Cookie) add_header Access-Control-Allow-Credentials true; # 处理 OPTIONS 预检请求 if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE"; add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"; add_header Access-Control-Max-Age 3600; add_header Access-Control-Allow-Credentials true; add_header Content-Length 0; add_header Content-Type text/plain; return 204; } }}
2023年12月12日
37 阅读
0 评论
0 点赞