简体   繁体   English

如何通过Symfony应用程序为Angular SPA提供index.html文件?

[英]How to serve index.html file for an Angular SPA from a Symfony application?

I have been working on a single page application project started a few weeks ago. 我一直在从事几个星期前开始的单页应用程序项目。 We've focused so far on the front-end part of the project, built with AngularJS, which allowed for the validation of many aspects of the projected final application. 到目前为止,我们一直专注于使用AngularJS构建的项目的前端部分,该部分允许验证最终应用程序的许多方面。

We're now setting up the web services and back end parts. 现在,我们正在设置Web服务和后端部分。 Due to reasons I have no control over, Symfony has been chosen by the studio with which I am under contract. 由于我无法控制的原因,我与之签有合同的工作室选择了Symfony。 I am therefore encountering configuration and setup problems that I would not have met, had I been in my usual Java+Spring boot setting. 因此,如果我处于常规的Java + Spring引导设置中,那么我将遇到本来不会遇到的配置和设置问题。

The existing application has this folder structure: 现有应用程序具有以下文件夹结构:

root-client
|--bower_components
|--images
|--libs (dist files of bower_components)
|--scripts
|--styles
|--views
|--index.html

I've initialized the Symfony project as per https://jeremycurny.com/2016/03/27/symfony3-rest-api/ and it works fine, returning the test JSON responses I've set up. 我已经按照https://jeremycurny.com/2016/03/27/symfony3-rest-api/初始化了Symfony项目,并且工作正常,返回了我设置的测试JSON响应。 Folder structure: 资料夹结构:

root-rest-api
|--app
|--bin
|--src
|--tests
|--var
|--vendor
|--web
|--...

Both parts work exactly as intended. 这两部分均按预期工作。

The problem comes when attempting to have both parts run together, that is when, following recommendations I've read in the Symfony documentation that static files are to be served from web , I moved everything below root-client under root-rest-api/web . 当尝试使两个部分一起运行时会出现问题,即遵循我在Symfony文档中阅读的建议,即要从web提供静态文件的建议时,我将所有内容都移到了root-client下的root-rest-api/web

The problem is that index.html can no longer be reached from the web browser. 问题在于无法从Web浏览器访问index.html More clearly, http://localhost/ used to start the application. 更清楚地, http://localhost/用于启动应用程序。 After moving the "static" files under web , I now get this JSON response: 将“静态”文件移至web下之后,我现在得到以下JSON响应:

{"error":{"code":404,"message":"Not Found"}}

The cause of the error is easy to figure out: no controller is registered to the '/' path. 错误原因很容易找出:没有控制器注册到'/'路径。 As a consequence, I have written this: 结果,我这样写:

namespace AppBundle\Controller;

use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends FOSRestController
{
    /**
     * @Rest\Get("/")
     */
    public function indexAction(Request $request)
    {
        return $this->render('index.html');
    }

This code defines a specific route for '/', which is what this answer to a similar question (in a Python environment instead of PHP or Symfony) points to. 这段代码为“ /”定义了一条特定的路由,这是对类似问题(在Python环境中而不是PHP或Symfony中)的回答

I get a 500 HTTP error code, probably due to my improper use of render : all examples I've found online refer to Twig templates, for instance, the documentation about rendering templates . 我收到了500个HTTP错误代码,这可能是由于我对render使用不当所致:我在网上发现的所有示例都涉及Twig模板,例如, 有关渲染模板的文档 Even more undesirable to me, the examples place templates in app/Resources/views . 对于我来说,更令人讨厌的是,这些示例将模板放置在app/Resources/views

Is there a means of returning the existing index.html file from the web folder? 有没有办法从web文件夹返回现有的index.html文件? I'm trying to avoid turning all our HTML fragments into Twig templates and thus redefining the Angular delimiters. 我试图避免将我们所有的HTML片段都转换为Twig模板,从而重新定义Angular分隔符。 Maybe that there's an obvious answer, but this is my first project using Symfony. 也许有一个明显的答案,但这是我使用Symfony的第一个项目。

In case it's not possible, I'll treat the client and server parts as distinct projects and serve them as distinct layers of the architecture, instead of blending both as is the case with Java and Spring boot projects or classic Symfony projects. 在不可能的情况下,我会将客户端和服务器部分视为不同的项目,并将它们用作体系结构的不同层,而不是像Java和Spring引导项目或经典Symfony项目那样将两者融合在一起。

You always can use good old file_get_contents($index_html_path) , and send simple string response, in your case (Symfony 4): 在您的情况下,您总是可以使用旧的file_get_contents($index_html_path)并发送简单的字符串响应(Symfony 4):

    /**
     * @Route("/", name="index_page")
     */
    public function indexAction(Request $request)
    {
        return new Response(file_get_contents($index_html_path));
    }

How to get path to index html? 如何获取索引html的路径? It is simple in controller: 在控制器中很简单:

    $index_html_path = $this->getParameter('kernel.project_dir') . '/public/index.html';

Or even so, if your index.html is simple and rarely changing (just copy-past content to your controller): 甚至是这样,如果index.html很简单并且很少更改(只需将复制内容复制到您的控制器中):

    /**
     * @Route("/", name="index_page")
     */
    public function index() {
        ?>
        <!doctype html>
        <html lang="en">
        <head>
            <title></title>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        </head>
        <body>
        <div id="root"></div>
        </body>
        </html>
        <?php
        return new Response("");
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM