ResponseListener更改Content-Type资产

时间:2015-05-30 13:20:50

标签: symfony assetic

在我的开发环境中添加响应侦听器之后,我的css文件的内容类型从text / css切换到text / html。我的目标只是为我的symfony应用程序的所有响应添加一些缓存标头。

服务定义:

response_listener:
    class: AppBundle\EventListeners\ResponseListener
    tags:
        - { name: kernel.event_listener, event: kernel.response }

服务类:

<?php

namespace AppBundle\EventListeners;

use Symfony\Component\HttpKernel\Event\FilterResponseEvent;

class ResponseListener
{
    public function onKernelResponse(FilterResponseEvent $event)
    {
        // while testing I do nothing special here
        $response = $event->getResponse();
        $event->setResponse($response);
    }
}

资产配置:

assetic:
    debug:          "%kernel.debug%"
    use_controller: true
    bundles:        [ AppBundle ]
    filters:
        cssrewrite: ~

Twig标签:

{% stylesheets
    'bundles/app/css/login.css'
    filter='cssrewrite' %}
    <link rel="stylesheet" type="text/css" href="{{ asset_url }}"/>
{% endstylesheets %}

使用text / html作为内容类型时,不会呈现css。 仅删除服务定义使其再次正常工作。 在prod环境中,它可以使用或不使用响应侦听器,并且js文件完全没有问题。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

我有一个非常类似的问题,虽然我没有在symfony的核心包上完全跟踪它,但我认为这是因为在开发实例上,资产确实使用控制器来渲染CSS。

我实际上已停止查看我发现的那一刻,就像你一样,我的config_dev.yml声明了:

assetic:
    use_controller: true


所以我发现当你尝试在symfony中使用响应对象时,请求的格式在听取响应时会以某种方式丢失。 Symfony's own ResponseListener似乎set text/html as a defaullt,因为没有定义内容类型。

虽然修复很容易:
在课程ResponseListener中,我们的听力功能变为

public function onKernelResponse(FilterResponseEvent $event)
{
    $response = $event->getResponse();

    // We do get the params of the route
    $route_params = $event->getRequest()->get('_route_params');

    // And we figure out if it should be in a specific format
    if(isset($route_params['_format'])) {

        // getMimeType function on the Request object come in handy for this job
        $format = $event->getRequest()->getMimeType($route_params['_format']);

        // Then we just reinstate the right Content Type
        $response->headers->set('Content-Type', $format);
    }
    $event->setResponse($response);
}

虽然您在生产环境中永远不会遇到此问题,例如您所声明的,因为您的资产是由命令行资产工具(不是控制器)转储的。

实际上,如果你在ResponseListener

中做了类似的事情
die($event->getRequest()->get('_controller')); 

您可以通过其直接网址导航到css文件,您会看到此显示:

assetic.controller:render

当您拥有该配置时,完全验证css通过资产包控制器呈现视图即时构建的事实综上所述。