Nginx 配置前端 HTML5 History 路由

由于 Vue、React 等现代前端框架的前端 History 路由,在服务端并没有实际对应的物理路径和文件,所以使用 Nginx 的默认配置直接访问路由或刷新路由时,会导致 404 错误。

在 Nginx 中使用 try_files 配置对不存在的文件或路径进行处理,返回指定文件即可解决 History 路由 404 的问题。

以下针对几种情况给出配置示例,并简单讲解相关配置。

前端项目在 Nginx 服务根目录下

服务端目录结构如下:

1
2
3
+-- html
+-- index.html
+-- bundle.js

nginx 配置如下:

1
2
3
4
5
6
7
8
9
...

location / {
root html;
try_files $uri $uri/ index.html;
index index.html index.htm;
}

...

location 配置对访问路径进行匹配:

1
2
3
4
Syntax:	location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default: —
Context: server, location

root 指定请求对应在服务器上对应的根目录:

1
2
3
Syntax:	root path;
Default: root html;
Context: http, server, location, if in location

try_files 配置将依次查找后面的文件或路径,不存在时查找下一个,因此最后一个文件必须存在,否则将产生 500 错误。

1
2
3
4
Syntax:	try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location

index 指定该请求路径的索引

1
2
3
Syntax:	index file ...;
Default: index index.html;
Context: http, server, location

这里使用 try_files 配置将不存在的路径访问统一返回了 index.html 文件,这样就交由前端项目进行 History 路由的处理。

需要注意的时,如此配置后将不会产生 404 访问,因此前端路由中应对不存在的路由进行 404 页面的处理。

前端项目在 Nginx 服务子目录下

服务端目录结构如下:

1
2
3
4
5
6
7
+-- html
+-- project1
| +-- index.html
| +-- bundle.js
+--- project2
+ -- index.html
+ -- bundle.js

分别为 project1project2 配置 try_files:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...

location / {
root html;
index index.html index.htm;
}

location /project1 {
root html;
try_files $uri $uri/ /project1/index.html;
index index.html index.htm;
}

location /project2 {
root html;
try_files $uri $uri/ /project2/index.html;
index index.html index.htm;
}

...

前端项目在其他目录下

目录结构如下:

1
2
3
4
5
6
7
8
+-- nginx
+-- html
| +-- project1
| | +-- index.html
| | +-- bundle.js
+-- project2
+ -- index.html
+ -- bundle.js

project1project2 使用前端路由的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...

location / {
root html;
index index.html index.htm;
}

location /project1 {
root html;
try_files $uri $uri/ /project1/index.html;
index index.html index.htm;
}

location /project2 {
root ./;
try_files $uri $uri/ /project2/index.html;
index index.html index.htm;
}

...