Symfony路由配置:忽略指定路由及Vue.js同域名部署404问题
同域名下Symfony4 + Vue.js History模式共存解决方案
我之前处理过不少类似的前后端同域名部署场景,这个问题的核心是让Symfony主导路由的同时,把指定范围的请求交给Vue接管,还要解决History模式下的404问题,下面是分步解决技巧:
1. 调整Symfony路由配置,给Vue留兜底入口
首先要在Symfony的路由配置里,把非Symfony专属的路由都导向Vue的入口页面,注意路由顺序很重要——Symfony的原有路由要放在前面,Vue的兜底路由放在最后。
修改config/routes.yaml:
# 保留你的Symfony原有路由(比如注解路由) app: resource: '../src/Controller/' type: annotation # Vue的兜底路由,放在所有Symfony路由之后 vue_app: path: /{vueRouting} controller: App\Controller\VueController::index requirements: # 这里用正则排除你想留给Symfony的路由前缀,比如api、admin vueRouting: '^(?!api|admin).*$' defaults: vueRouting: null
然后创建VueController,用来返回Vue打包后的index.html:
// src/Controller/VueController.php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; class VueController extends AbstractController { public function index(): Response { // 这里替换成你Vue打包后index.html的实际路径 return $this->file('vue/dist/index.html'); } }
2. 配置Vue.js适配History模式
确保Vue路由开启History模式,并且打包路径对应Symfony的public目录:
路由配置(src/router/index.js)
import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: Home }, // 你的其他Vue路由... ] const router = new VueRouter({ mode: 'history', base: '/', // 同域名部署,base设为根路径即可 routes }) export default router
打包路径配置(新建/修改vue.config.js)
module.exports = { // 把Vue打包产物直接输出到Symfony的public目录下 outputDir: '../symfony-project/public/vue/dist' }
3. 服务器配置(解决History模式404的关键)
Vue的History模式下,直接访问子路由(比如/about)时,服务器会默认找对应的文件,找不到就返回404。所以需要配置服务器,把这类非文件请求转发到Symfony的入口文件index.php,再由Symfony路由导向Vue。
Apache配置(修改Symfony项目根目录或public目录下的.htaccess)
<IfModule mod_rewrite.c> RewriteEngine On // 先处理Symfony专属路由(比如api、admin) RewriteCond %{REQUEST_URI} ^/(api|admin) RewriteRule ^(.*)$ index.php [QSA,L] // 所有非文件/非目录的请求,都转发到index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [QSA,L] </IfModule>
Nginx配置(修改站点配置文件)
server { listen 80; server_name your-domain.com; root /path/to/symfony-project/public; // 所有请求先尝试找文件,找不到就转发到index.php location / { try_files $uri $uri/ /index.php$is_args$args; } // Symfony专属路由直接走PHP解析 location ~ ^/(api|admin)/ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; // 替换成你的PHP-FPM路径 fastcgi_param SCRIPT_FILENAME $document_root/index.php; include fastcgi_params; } // 处理PHP核心请求 location ~ ^/index\.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
注意事项
- 一定要保证Symfony路由的顺序:Symfony专属路由在前,Vue兜底路由在后,否则Symfony会先匹配到兜底路由,导致原有路由失效。
- 如果需要排除更多Symfony路由,只需要在
vue_app路由的requirements里添加对应的前缀,比如^(?!api|admin|user).*$。 - 打包Vue项目时,确保
outputDir路径正确,且Symfony的public目录有写入权限。
内容的提问来源于stack exchange,提问作者darkiron
相关产品推荐
相关产品推荐

