• 前言

    最近负责学院某系统开发,计划前后端分离部署在校内服务器。但是计划赶不上变化,学校网络中心的一波骚操作可没让我少折腾,尤其是项目部署运维方面。Nginx在应对各种奇怪需求的时候踩了不少坑。

1. Nginx和Vue路由冲突

  • Vue路由有两种模式,一种history模式,URL是这样的http://xxxx.com/home?query=xxx,但是默认是hash模式,URL会多出一个#,http://xxxx.com/#/home?query=xxx
  • 其中“#”是无法被Nginx解析的,因为“#”被认为是一个网页中的位置,在其右边是标识符,代表着这个位置。因此http请求是包括“#”的,它的作用仅仅在控制浏览器的时候才会体现,而对服务器完全无用,因此Nginx也无法解析它。
  • 另外,改变“#”后的部分并不会触发网页的重载,但是会改变浏览器的历史记录。vue-router也是通过监听“#”后的路由来实现单页应用的。
  • 解决方案

    1. 将vue路由切换到history模式,
    	let router = new VueRouter({
    		mode: 'history',
    		routers: [],
    	})
    
    1. 在Nginx中配置
    	location / {
    		try_files $uri $uri/ /index.html;
    	}
    

2. Nginx端口复用

  • 学校网络中心只对公网开放80端口,这导致后台服务完全无法通过公网访问,但是我并没有做后端渲染,依旧打算采用前后端分离的模式开发。因此需要将80端口复用,同时监听前端和后端的请求。
  • 解决方案

    1. 在后台所有请求url中加上/api,以便和前端的页面请求区分。
    2. 在nginx中,监听80端口,配置location
    	location ^~ /api/ {
    		# 匹配任何以 /api/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
    		proxy_pass: http://localhost:xxxx #后端反代地址
    	}
    	# location / 的配置保持不变,最好放在最后。
    
    1. 其中反向代理路径配置可以参考这里

3. Nginx的几个重要参数

  1. client_max_body_size
    在有较大文件上传下载时一定要注意这个参数,如果配置不当,可能直接导致net:ERR这样的玄学报错。作用域为 http,server,loaction
  2. proxy_intercept_errors
    当被代理的后端服务器的响应状态码大于等于300时,决定是否直接将响应发送给客户端,亦或将响应转发给nginx由error_page指令来处理。这个默认为off,如果要自定义错误页面必须改为on。作用域为http,server,location
  3. fastcgi_intercept_errors
    当FastCGI后端服务器响应状态码大于等于300时,决定是否直接将响应发送给后端客户端,或者将响应转发给nginx由 error_page指令来处理。与上一个参数类似。

What is broken can be reforged.