篇首语
大家好,我是“全栈”,是我的笔名。我是一个来自广州的高中独立开发者,喜好一切与电脑有关的东西,随时写些随笔。
写下这篇文章前,我已经累计在电脑前为这个问题,解决了足足4个小时。当我敲下键盘时,不免心生感慨…特写文一篇,以做后记,启示世人
为了让这篇踩坑+教程文更直戳重点,我在这里列出来这篇文章涉及到的:
- Vue.js 及 Vue Router
- SPA单页应用
- Webpack打包(涉及到了Quasar框架)
- 启用了Html5 History的Route模式
- 部署到Nginx
- 部署到子目录,旨在于后端共存
- 踩坑了nginx反向代理及url匹配
- 简要介绍一种较为简易的同域前后端分离的部署架构
- 可能是全网最详细(啰嗦)的
说实话,在CSDN上那么用心写文章的,还被你看到,真是难得。何不点赞关注转发三连再走?
部署方向
最近接了一个任务,我承担前端开发。前端是一件很美好的事情,两三天写完了,但就在部署的时候,噩梦来了。
- 我们要求,同时因为跨域问题,前后端必须部署在同一个域名下,我们称之为https://hole.com,以有利于RESTful API的请求
- 因此,我希望可以在https://hole.com/webapp下作为SPA的访问链接,而https://hole.com/api/…则就是后端的链接
- 同时,我的Vue Router启用了h5 history模式,即https://hole.com/webapp/user/login这样的链接,是SPA处理的(就像https://hole.com/api/user/login是后端处理的一样)
- ok那开始吧
部署
这里是我总结了四个小时探索经验给出的方向,说真的全网说到nginx配置的都是复制黏贴,相信很多人都是看到能用就复制(包括我,最后发现解决问题还是要知其所以然,互勉)
Quasar 配置(使用Quasar可省略Router Webpack的配置)
子路径是/webapp
build: {
vueRouterMode: 'history',
vueRouterBase: '/webapp',
publicPath: '/webapp'
}
Vue Router配置
const Router = new VueRouter({
mode: 'history',
base: '/webapp'
...
})
Webpack配置/Quasar配置
//如果你使用Webpack打包
export default {
output: {
publicPath: '/webapp',
}
Nginx的配置A-主服务器
这里指的是监听https://hole.com的服务器,其实也是接受后端请求的服务器(vhost)
server {
listen 443 ssl;
server_name hole.com;
server_tokens off;
error_log hole.log;
root /home/www/hole;
index index.php index.html index.htm;
if ($request_method !~ ^(GET|POST|HEAD)$ ) {
return 444;
}
#前端匹配部分
location /webapp/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://localhost:10250/;
#这个一定要/结尾,不结尾搞死人,等下说
}
#后端匹配部分
location / {
if (!-e $request_filename) {
rewrite ^/index.php(.*)$ /index.php?s=$1 last;
rewrite ^(.*)$ /index.php?s=$1 last;
break;
}
}
location ~ .*\.php$ {
fastcgi_pass unix:/run/php/php7.1-fpm.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi.conf;
}
}
我们是用反向代理来代理前端的请求,为前端单独设置一个vhost,任何发送到https://hole.com/webapp/的请求都会被代理到10250端口的vhost中单独处理。
坑:一定注意proxy_pass http://localhost:10250/;
这一行末尾的/,只有以/结尾,https://hole.com/webapp/hello发送代理服务器链接才是/hello,而不是/webapp/hello。具体可看我写的文章。
Nginx的配置B-前端
server {
listen 10250;
error_log webapp.log;
location / {
try_files $uri $uri/ /index.html;
root /home/www/hole/webapp;
index index.html;
}
}
在这里我们单独设置一个服务器监听前端的请求,当做他是一个根路径为/的服务器。这也是为什么反代中,proxy_pass http://localhost:10250/;
需要末尾加/,截去weapp路径的原因。
后果和原理
如果我发起了https://hole.com/webapp/user,则会被A服务器(充当总入口)的/webapp location匹配到,进入B服务器中。并且进入的路径是/user,符合h5history实现,会优雅被VueRouter处理到。
如果发起https://hole.com/api,则被A的/ locaiton匹配到,交由A配置的php后端处理。
至此解决了同域部署下,SPA与后端共存的方案
总结与补充
总结:解决问题,知其所以然真的很重要。之前解决nginx的配置问题总是靠复制黏贴,最后,遇到复杂场景的时候要自己撰写的时候,你还是要还的。我还是个学生,做到的,只能是一点一滴。
补充:经过这四个小时,鄙人足足看了不下百篇nginx配置的相关知识,于是我会在接下来撰写一些关于nginx配置的小技巧和感悟,欢迎关注。
更多文章
- Nginx中URL匹配小计及反向代理中路径小坑
- Nginx try_files 非复制黏贴原创全解析
说实话,在CSDN上那么用心写文章的,还被你看到,真是难得。何不点个赞关注转发下再走?
欢迎交流~~~