查看: 386|回复: 3

Vue history模式二级目录Nginx配置方法

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式
Vue 项目使用 history 路由模式后,部署到服务器二级目录时,刷新页面或直接访问子路径容易出现资源路径错乱、页面无法打开的问题。本文基于 Vue 2.6.14、vue-router 3.5.3 和 history 模式,梳理从根目录部署到二级目录部署的配置差异,重点说明 publicPath、router base 与 Nginx try_files 的对应关系。

一、先看根目录部署的配置

当项目部署在域名根目录时,vue.config.js 中的 publicPath 配置为根路径:
  1. // vue.config.js
  2. module.exports = {
  3.   publicPath: '/'
  4. }
复制代码

Nginx 需要把找不到的静态资源请求交回 index.html,常见配置如下:
  1. location / {
  2.   try_files $uri $uri/ @router;
  3.   index index.html index.htm;
  4. }
  5. location @router {
  6.   rewrite ^.*$ /index.html last;
  7. }
复制代码

这里的 try_files 会依次检查原始 URI、URI 加斜杠后的目录、以及目录下的 index 文件是否存在。如果都不存在,就把请求内部重定向到 @router,再由 rewrite 交给 /index.html 处理。这样做的目的是让前端路由接管地址,页面刷新时仍然能回到 Vue 应用,而不是直接返回 Nginx 的找不到页面。

index 指令用于给 Nginx 指定默认首页的查找顺序,配置中的 index.html、index.htm 会按顺序查找并返回第一个存在的文件。rewrite 中的 last 表示重写后重新匹配 location,属于内部重写标记;它不是外部 301 跳转,排查时不要把 last 和 301 状态码混为一谈。

二、部署到二级目录的需求与原理

假设访问地址是:
  1. 域名/h5/index.html
复制代码

也就是项目放在服务器的 h5 目录下。此时配置的核心原则是:页面地址中所有与 /h5/ 相关的路径,都要能正确指向二级目录下的 h5/index.html,并且打包生成的 js、css 等静态资源请求也要带上 /h5/ 前缀。

三、二级目录的三处关键配置

1. 打包配置 publicPath

publicPath 要对应服务器上的二级目录名。二级目录叫 h5,就配置为 /h5/:
  1. // vue.config.js
  2. module.exports = {
  3.   publicPath: '/h5/'
  4. }
复制代码

这样打包后的静态资源 URL 会携带 h5 前缀,避免浏览器仍然去根目录查找 js、css 文件。

2. 路由配置 base

history 模式下需要给 vue-router 设置基础路径,二级目录为 h5 时配置如下:
  1. // router.js
  2. const router = new VueRouter({
  3.   mode: 'history',
  4.   base: '/h5/',
  5.   routes: []
  6. })
复制代码

base 的作用是让前端路由生成的地址都基于 /h5/,与 publicPath 和 Nginx 的 location 保持一致。

3. Nginx 配置

Nginx 中为二级目录单独配置 location,并把找不到的请求回退到 /h5/index.html:
  1. location /h5/ {
  2.   try_files $uri $uri/ /h5/index.html;
  3. }
复制代码

这段配置的含义是:请求进入 /h5/ 后,先尝试匹配真实文件或目录;如果不存在,就内部转发到 /h5/index.html,由 Vue 前端路由继续处理。与根目录配置相比,这里不需要额外的 @router 命名 location,直接把回退目标写成二级目录下的 index.html 即可。

四、配置一致性检查

二级目录部署最容易出问题的地方,是三处配置没有统一。以 h5 为例:

- vue.config.js 中 publicPath 是 /h5/;
- vue-router 中 base 是 /h5/;
- Nginx 中 location 是 /h5/,try_files 回退目标是 /h5/index.html。

这三处都带上 h5 后,打包生成的 js、css 等资源请求才会携带 h5 前缀,页面刷新时 Nginx 也能把请求交回 /h5/index.html。若其中任意一处漏写或写成根路径,就可能出现首页能打开但刷新子路由失败、静态资源 404、路由跳转后地址缺少二级目录等现象。

五、适用场景与排查思路

该方案适用于 Vue 2 + vue-router 3 的 history 模式项目,尤其是需要把前端应用挂载到域名某个子目录下的部署场景。排查时建议按以下顺序检查:

1. 确认服务器上的实际目录名与 publicPath、base、Nginx location 是否完全一致;
2. 查看打包产物中静态资源引用的 URL 是否带二级目录前缀;
3. 检查 Nginx 的 try_files 回退路径是否指向 /二级目录/index.html;
4. 直接访问二级目录首页和子路由地址,观察刷新后是否仍能回到 Vue 应用。

整体来看,Vue history 模式部署到二级目录并不需要复杂改写,关键是让打包路径、路由基础路径和 Nginx 回退路径三者对齐。只要保持目录名一致,history 模式在二级目录下也能正常刷新和访问。
回复

使用道具 举报

发表于 3 小时前 | 显示全部楼层

Re: Vue history模式二级目录Nginx配置方法

感谢楼主整理,三处配置对齐这个思路很清晰,之前踩坑就是栽在这上面。我补充两个容易忽略的小点:一是 publicPath、router base 和 Nginx 的 location 末尾都建议带斜杠 /h5/,保持完全一致,否则可能匹配不上;二是排查时可以先用浏览器开发者工具看打包后的 js/css 请求地址是不是以 /h5/ 开头,如果还指向根目录,问题基本就在 publicPath 上,不用先去翻 Nginx。另外楼主提到的刷新子路由失败、首页能开但跳转地址丢前缀这些现象,确实是最常见的问题,按第五部分的顺序排查很省时间。
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层

Re: Vue history模式二级目录Nginx配置方法

这篇整理得很清楚,尤其是把 publicPath、router base 和 Nginx location 三处必须统一到 /h5/ 这一点讲透了,排查顺序也很实用。补充两个容易踩的小点:第一,三处配置的末尾斜杠最好保持一致,访问 /h5 时如果没带斜杠,可能先被 Nginx 处理成目录跳转,建议实际测试一下带斜杠和不带斜杠两种地址;第二,确认 Nginx 的 root 指向的是站点根目录,这样 try_files 回退到 /h5/index.html 时才能找到真实文件。整体思路没问题,按“打包产物资源前缀、路由基础路径、Nginx 回退目标”逐项核对,二级目录部署基本就稳了。
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层

Re: Vue history模式二级目录Nginx配置方法

感谢楼主分享,这篇把 publicPath、router base 和 Nginx try_files 三者的对应关系讲得很清楚,尤其是“三处必须都带 h5”这个一致性检查,确实是二级目录部署最容易踩的坑。我之前就遇到过首页能打开、刷新子路由就 404 的情况,最后排查发现是 base 还留着根路径没改。 有一点想确认下:文中 Nginx 的 location 是 /h5/,如果用户访问的是 域名/h5(不带尾斜杠),会不会被 Nginx 匹配到别的 location 或者跳转异常?这种情况是不是需要额外加一条 location = /h5 做重定向?另外如果服务器上 h5 目录的实际路径和 root 指令对应的根目录不完全一致,try_files 的回退目标 /h5/index.html 是不是也要跟着确认下能正确命中文件。 整体思路很实用,按第五部分那四步排查顺序走,基本能定位到问题所在,收藏了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-31 05:41 , Processed in 0.026981 second(s), 28 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部