前后端分离实践
背景介绍
原本前后端代码是分别独立的,在代码仓库里是两个仓库,但不知之前的开发人员出于何种考虑,在项目部署时,又将前端代码合并到了后端
前后端分离步骤
总体思想
前端打包后上传至Nginx服务器,后端打包后使用Docker容器部署
安装Nginx容器
目录结构
docker-compose.yml文件
version: '3'
services:
nginx:
restart: always
container_name: nginx
image: nginx
ports:
- 80:80
- 443:443
volumes:
# 此目录一定要挂载!
- /data/nginx/html:/usr/share/nginx/html
- /data/nginx/logs:/var/log/nginx
# 有可能会出现不能挂载,这个时候用手动拷贝配置文件就行
- /data/nginx/nginx.conf/:/etc/nginx/nginx.conf
- /data/nginx/etc/cert:/etc/nginx/cert
- /data/nginx/conf.d:/etc/nginx/conf.d
environment:
- NGINX_PORT=80
- TZ=Asia/Shanghai
privileged: true
nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
# 注意要添加这一行
include /etc/nginx/conf.d/*.conf;
}
default.conf
server{
listen 80;
server_name localhost;
charset utf-8;
location / {
# 此处一定要改成nginx容器中的目录地址,宿主机上的地址容器访问不到
# 命令必须用 root, 不能用 alias
root /usr/share/nginx/html/dist;
# try_files $uri $uri/ =404;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
注一
使用Nginx 容器时,想查看Nginx的日志应该查看对应的挂载目录,而不是使用docker logs命令
注二
表示前端的每一个请求路径都需要一个前缀/resource,区别于后端请求路径
资源路径为/zgbj/resource目录下
注三
在Nginx的配置文件中,缩进一般不会对配置文件的解析和执行产生影响;但适当的缩进可以提高配置文件的可读性和易于维护性
上传前端文件
目标路径
/data/nginx/html
注:实际运行时,Nginx读取的是容器内的文件,即存储在/usr/share/nginx/html目录下的文件,所以这个目录一定要挂载!!!
浏览器路径解析
当我们在浏览器中输入http:localhost:80后,该请求会被Nginx容器拦截,然后分发至/usr/share/nginx/html/dist/index.html,即项目首页
修改前端请求后端接口端口号
原本前后端合并打包时,前端首页是通过后端的一个controller进行跳转的,即是通过8080这个端口到达的前端页面,此时前端设置的后端接口路径为/,故刚好可以访问后端接口;
但现在前后端项目分离,一个服务器不可能出现两个8080端口,故前端不可能通过8080端口进行访问,此时有两种解决方案:
第一种:前端写清楚后端接口具体地址及端口(不推荐)
axios.defaults.baseURL = 'http://1.2.3.4:8081'
第二种方法:使用Nginx来进行端口转化(推荐)
因为本质上就是端口不匹配
前端配置修改
axios.defaults.baseURL = '/api'
后端配置修改
# 开发环境配置
server:
# 服务器的HTTP端口,默认为8080
port: 8080
servlet:
# 应用的访问路径
context-path: /api
Nginx转发
location /api {
proxy_pass http://172.31.16.31:8080;
}
注:为什么前后端分离后前端配置不能使用通配符/
因为通配符/的作用就是将浏览器中输入的url地址及端口作为前端访问后端接口的地址及端口
但前后端分离后,前端和后端的端口号必定是不同的,故不能使用;
遇到的问题
上传前端文件后,浏览器显示403,Nginx日志如下显示
directory index of "/usr/share/nginx/html/" is forbidden
解决方法
本质并不是文件夹权限问题,我的情况是找不到index.html文件,所以添加文件或者修改相应路径即可
参考文章
【3】前端配置后端接口地址