vue-router history 模式与 nginx 配置

vue-router 默认是 hash 模式,在 url 后面会有一个 # 号,在一些情况下,因为 # 号的原因,会让后面的 uri 丢失导致 url 跳转出现问题(比如在微信内跳转异常)。这时候可以使用 history 模式,取缔 # 号,这时候需要在服务器进行配置。

nginx 的一些知识点

location

语法规则:location [=|~|~*|^~|@] pattern { … }

  • = 开头表示精确匹配
  • ~ 开头表示区分大小写的正则匹配
  • ~* 开头表示不区分大小写的正则匹配
  • ^~ 开头表示uri以某个常规字符串 URI 开头进行匹配。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
  • / 通用匹配,任何请求都会匹配到。

root

根路径配置,在匹配到 location 的 uri 路径后,指向 root 配置的路径,并把 uri 路径加在 root 路径后面。

1
2
3
location /mc/ {
root /home/mine/files/;
}

当我访问 http://[host]/mc/test.png 时,实际上返回的文件路径为 /home/mine/files/mc/test.png

alias

别名配置,在匹配到 location 的 uri 路径后,指向 alias 配置的路径

1
2
3
location /mc/ {
alias /home/mine/files/;
}

当我访问 http://[host]/mc/test.png 时,实际上返回的文件路径为 /home/mine/files/test.png

try_files

try_file 的作用类似与重定向

1
2
3
4
location /mc/ {
alias /home/mine/files/;
try_files $uri $uri/ /mc/index.html;
}

当访问 http://[host]/mc/example时,try_files 首先会在 /home/mine/files/ 目录下找是否有 example 这个文件,有则返回,未找到则找是否有 example 这个目录,有则返回,未找到则发起一个服务器内部发起重定向请求到 http://localhost/mc/index.html

Vue Router配置

当设置了 modehistory 时,Vue Router 有一个 base 的配置,假如 SPA 放入在一个 [host]/mc/ 服务下时,可以将 base 设置为 /mc/

此时 nginx 的配置可以更新为:

1
2
3
4
5
location /mc {
alias /home/mine/files;
index inde.html;
try_files $uri $uri/ /mc/index.html;
}

将打包之后的代码放入 /home/mine/files 根目录下。

假如我需要保留访问 [host]/mc/ 下的静态资源(比如图片),同时由多个 SPA 应用部署在 /mc/ 下进行访问。

首先,有一个 A 应用([host]/mc/a),B 应用([host]/mc/b)。

  • mode 设置为 history
  • 将 A 应用 base 设置为 /mc/a/,打包后把代码放入 /home/mine/files/a/
  • 将 B 应用 base 设置为 /mc/b/,打包后把代码放入 /home/mine/files/b/
  • 创建文件夹 /home/mine/files/mc/,用于放置其他静态资源

更新 nginx 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
location /mc/ {
root /home/mine/files/;
}

location ^~ /mc/a {
alias /home/mine/files/a;
index index.html;
try_files $uri $uri/ /mc/a/index.html;
}

location ^~ /mc/b {
alias /home/mine/files/b;
index index.html;
try_files $uri $uri/ /mc/b/index.html;
}

此时

  • 访问 [host]/mc/test.png,实际上的文件路径为 /home/mine/files/mc/test.png
  • 访问 [host]/mc/a,实际上访问了 A 应用的根路由
  • 访问 [host]/mc/b,实际上访问了 B 应用的根路由