Vue 带slug的特定页面刷新问题:生产环境部署后访问返回404
问题根因
该问题是Vue客户端路由的典型配置问题:
- Vue Router默认开启HTML5 History模式时,所有路由跳转都是在浏览器端完成的,不会向服务器发送真实资源请求
- 开发环境下webpack内置的devServer默认配置了
historyApiFallback: true,所有不存在的路径请求都会自动回退返回index.html,因此刷新正常 - 生产环境打包后只有单个
index.html入口文件和静态资源,服务器没有配置回退规则时,直接访问子路由/刷新页面会向服务器请求对应路径的静态资源,不存在就返回404错误
解决方案
1. Nginx 服务器配置
修改nginx的站点配置文件,在location /块中添加try_files规则:
location / { root /usr/share/nginx/html; # 替换为你的站点静态文件存放路径 index index.html index.htm; try_files $uri $uri/ /index.html; # 核心配置:找不到资源就返回index.html }
修改后执行nginx -s reload重载配置即可生效。
2. Apache 服务器配置
在项目打包后的根目录下新建.htaccess文件,写入以下规则:
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] </IfModule>
注意需要提前开启Apache的mod_rewrite模块。
3. 原生Node.js 服务配置
如果用Node.js + express搭建静态服务,可安装connect-history-api-fallback中间件处理:
首先安装依赖:npm install connect-history-api-fallback
然后在服务代码中引入使用:
const express = require('express') const history = require('connect-history-api-fallback') const app = express() app.use(history()) // 放在静态资源托管中间件之前 app.use(express.static('dist')) // dist是打包后的静态资源目录 app.listen(3000)
4. 无服务器修改权限的备选方案
如果没有权限调整服务器配置,可以将Vue Router改为Hash路由模式,路径会带#符号,所有路由都在#后处理,不会发送到服务器,无需额外配置服务器:
// Vue Router 4.x 配置示例 import { createRouter, createWebHashHistory } from 'vue-router' const router = createRouter({ history: createWebHashHistory(), // 替换原本的createWebHistory routes: [...] })
该方案缺点是URL路径会带#,美观度稍差,部分第三方回调可能不支持带#的路径。
内容的提问来源于stack exchange,提问作者ljubo
相关产品推荐
相关产品推荐

