nginx

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > nginx > Nginx配置Vue路由模式

Nginx配置Vue项目Hash/History模式路由跳转错误的解决方案

作者:网罗开发

这篇文章主要为大家详细介绍了Nginx配置Vue项目Hash/History模式路由跳转错误的相关解决方案,文中的示例代码讲解详细,需要的小伙伴可以了解下

前言

最近在一个实际项目中,前端采用 Vue2,路由模式是 hash,后台通过 Nginx 部署。我们遇到一个让人头疼的问题:访问子路径路由 /inv/#/login 时,竟然跳转到了错误的页面。切换成 history 模式后路由倒是正常了,但一刷新页面,前端资源就加载失败,提示 MIME 类型错误。

这篇文章我会把问题的原因分析清楚,然后结合 Nginx 配置与 Vue 路由的特性给出可运行的解决方案,顺便给出实际案例中的 Demo 配置,方便你参考。

背景:Nginx 配置 + Vue 路由模式

在我们的项目中,存在两个前端子系统:

Nginx 配置如下:

location / {
    alias /data/web/sccmp/;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
}

location /inv/ {
    alias /data/web/inv/;
    index index.html index.htm;
    try_files $uri $uri/ /inv/index.html;
}

Vue 项目中,路由配置采用的是 hash 模式:

const router = new VueRouter({
  mode: 'hash',
  routes: [
    { path: '/login', component: Login },
    { path: '/dashboard', component: Dashboard }
  ]
})

遇到的问题

1.在 hash 模式下访问组长端 https://xxxx.xx.cppinfo.cn/inv/#/login

页面居然跳转到管理端的登录页,而不是组长端。

2.在 history 模式下刷新页面

出现错误:

Failed to load module script: Expected a JavaScript-or-Wasm module script 
but the server responded with a MIME type of "text/html".

简单说就是 JS 资源请求到了 HTML 文件,Nginx 没有正确返回对应的静态资源。

问题出在哪里

这个问题本质上分两层:

1.Hash 模式下路径混淆

Hash 模式的 URL 是 https://domain/inv/#/login,实际上 Nginx 并不知道 #/login 部分,它只处理 /inv/,而 Vue 的 JS 脚本却从 / 路径下去加载资源,导致加载的是管理端的 index.html。

2.History 模式下资源路径错误

在 history 模式下,Vue 的 URL 例如 /inv/login,Nginx 需要把所有未知路径回退到 /inv/index.html。如果配置不对,就会把资源请求(比如 /inv/js/app.js)错误地 fallback 到 HTML,从而导致 MIME type 错误。

如何解决

方案一:继续使用 Hash 模式(推荐初学者)

如果项目允许继续用 hash 模式,需要确保 每个子系统的资源路径是独立的,避免加载错目录。

在 Vue 的 vue.config.js 中设置 publicPath

// vue.config.js
module.exports = {
  publicPath: '/inv/',  // 对应组长端的部署路径
  outputDir: 'dist',
  productionSourceMap: false
}

这样构建出来的资源都会挂在 /inv/ 下,避免冲突。

Nginx 保持原配置即可。

方案二:使用 History 模式(推荐最终方案)

History 模式对 URL 更友好,但需要 Nginx 配置精确区分资源和路由。

Nginx 修改如下:

location / {
    root /data/web/sccmp;
    index index.html;
    try_files $uri $uri/ /index.html;
}

location /inv/ {
    root /data/web/inv;
    index index.html;
    # 只针对 html 路由回退
    try_files $uri $uri/ /index.html;
}

关键点:

实战 Demo 配置(可运行)

假设我们有两个 Vue 项目,构建产物分别在 /data/web/sccmp//data/web/inv/

Vue 配置 vue.config.js

// 管理端 vue.config.js
module.exports = {
  publicPath: '/',
  outputDir: 'dist-admin',
}

// 组长端 vue.config.js
module.exports = {
  publicPath: '/inv/',
  outputDir: 'dist-inv',
}

Nginx 配置:

server {
    listen 80;
    server_name demo.local;

    location / {
        root /data/web/sccmp;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    location /inv/ {
        root /data/web/inv;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
}

这样:

总结

我的建议是:开发初期可以用 Hash 模式省心,上线前建议切换到 History 模式,并仔细配置好 Nginx。

到此这篇关于Nginx配置Vue项目Hash/History模式路由跳转错误的解决方案的文章就介绍到这了,更多相关Nginx配置Vue路由模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文