我无法让SPA设置中的Symfony 4正常工作。
具体来说,当我使用React-router链接导航时,一切正常。
但是,如果我尝试直接访问任何路由(家庭除外),Symfony会拦截它,当然会为未找到的路径抛出错误。
将Symfony放在子域中并仅将其用作API的替代方法是不可行的,因为我需要框架提供的所有用户和会话管理工具。
当然,对于后端的所有API调用,我都需要Symfony的路由。
我正在使用Symfony 4的默认目录结构,只在顶层为所有react / redux代码添加目录/客户端。
构建代码放在/ public / build。
下我还尝试使用下面的代码将.htaccess文件放在/ public上,但这没有帮助。
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
由于
答案 0 :(得分:2)
可能会有一个解决方案。
具有路径注释的控制器,无论路径可能具有多少参数,所有路线都将通过与此注释作出反应来处理:
namespace App\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Annotation\Route;
class DefaultController extends Controller
{
/**
* @Template("default/index.html.twig")
* @Route("/{reactRouting}", name="index", requirements={"reactRouting"=".+"}, defaults={"reactRouting": null})
*/
public function index()
{
return [];
}
}
如果你有不应该通过反应处理的路线,你的注释可以如下排除它们 - 所有以api开头的路线都不会被反应处理:
@Route("/{reactRouting}", name="index", requirements={"reactRouting"="^(?!api).+"}, defaults={"reactRouting": null})
Twig Template,带根元素:
{% extends 'base.html.twig' %}
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('build/js/app.css') }}">
{% endblock %}
{% block body %}
<div id="root"><div>
{% endblock %}
{% block javascripts %}
<script type="text/javascript" src="{{ asset('build/js/app.js') }}"></script>
{% endblock %}
反应索引文件:
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Home from "./containers/Home";
import AboutUs from "./containers/AboutUs";
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route path="/" component={Home}/>
<Route path="/about-us" component={AboutUs}/>
</Switch>
</BrowserRouter>,
document.getElementById('root'));
我的安可配置:
var Encore = require('@symfony/webpack-encore');
Encore
// the project directory where compiled assets will be stored
.setOutputPath('public/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('/build')
.cleanupOutputBeforeBuild()
.enableSourceMaps(!Encore.isProduction())
// uncomment to create hashed filenames (e.g. app.abc123.css)
// .enableVersioning(Encore.isProduction())
// uncomment to define the assets of the project
// .addEntry('js/app', './assets/js/app.js')
// .addStyleEntry('css/app', './assets/css/app.scss')
// uncomment if you use Sass/SCSS files
// .enableSassLoader()
// uncomment for legacy applications that require $/jQuery as a global variable
// .autoProvidejQuery()
.enableReactPreset()
.addEntry('js/app', './react/index.js')
.configureBabel((config) => {
config.presets.push('stage-1');
})
;
module.exports = Encore.getWebpackConfig();
答案 1 :(得分:0)
我相信我找到了可能的设置。
在Symfony的routes.yaml中包含react-router路由,所有路由都指向生成React的根组件的同一个控制器。
所有其他路由(如API调用)都将正常设置。
//config/routes.yaml
//all routes handled by PWA(react-router) pointing to same controller
home:
path: /
controller: App\Controller\IndexController::index
account:
path: /account
controller: App\Controller\IndexController::index
如果有人知道其他设置,请分享。
答案 2 :(得分:0)
解决这个问题的正确方法是像这样设置路由注释:
/**
* @Route("/{reactRouting}", name="index", priority="-1", defaults={"reactRouting": null}, requirements={"reactRouting"=".+"})
*/
public function index(): Response
{
return $this->render('index.html.twig');
}
这里的魔法是使用“priority=-1”参数。这允许 symfony 使用路由来为 API 方法找到正确的路径,并且只有当没有找到路由时,React 路由器才会启动,寻找它的路由。如果也没有 React 路由,你应该使用 React 应用程序中的一些“NotFound”组件来处理它。
通过这种方法,您仍然可以使用 SPA,但也可以在同一个应用中定义所有逻辑并使用 API。