Symfony中的php – ResponseListener导致在开发模式下从apache导致重复的头文件“Content-Type”

前端之家收集整理的这篇文章主要介绍了Symfony中的php – ResponseListener导致在开发模式下从apache导致重复的头文件“Content-Type”前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在Mac上的MAMP PRO设置上运行Symfony应用程序.在我的symfony应用程序中,我使用一个包含以下函数的ResponseListener:
/**
 * Handle OPTIONS calls and add Access-Control headers.
 *
 * @param FilterResponseEvent $event Filter response event
 */
public function onKernelResponse(FilterResponseEvent $event)
{
    // Don't do anything if it's not the master request.
    if (!$event->isMasterRequest()) {
        return;
    }

    $request = $event->getRequest();
    if ($request->getRealMethod() == Request::METHOD_OPTIONS) {
        $response = new Response();
        $response->headers->set('Access-Control-Allow-Origin','*');
        $response->headers->set('Access-Control-Allow-Headers','Origin,X-Requested-With,X-Auth-Token,X-App-Version,Content-Type,Accept,Authorization');
        $response->headers->set('Access-Control-Allow-Methods','POST,GET,PUT');
        $event->setResponse($response);
    } else {
        $response = $event->getResponse();

        $response->headers->set('Access-Control-Allow-Origin','*');
        $response->headers->set('Access-Control-Allow-Credentials',true);
        $response->headers->set('Access-Control-Allow-Headers',PUT');
    }
}

这只是在浏览器中开发Ionic应用程序的一个解决方案,并处理来自应用程序的OPTIONS调用,而不会在那里出现错误.但这只是一个例子,我与使用ResponseListener的其他Symfony应用程序有同样的问题.

如果在prod环境中或在dev环境中运行它(如果没有发生错误),上述示例可以很好地工作.但是一旦我收到一个PHP错误,就会产生以下结果:

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator,you@example.com and inform them of the time the error occurred,and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.

Additionally,a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

如果我查看apache_error.log它说:

FastCGI: comm with server "/Applications/MAMP/fcgi-bin/PHP7.0.13.fcgi" aborted: error parsing headers: duplicate header 'Content-Type',referer: http://app.domain/app_dev.PHP/my-route

这似乎只发生在PHP错误.如果我例如抛出一个NotFoundHttpException

throw new NotFoundHttpException("Test exception");

我得到了通常的Symfony错误页面.

如果我做类似的事情

new ClassDoesNotExist();

它会导致内部服务器错误.

我知道这是由于ResponseListener,因为在我出现退出时,会出现Symfony错误页面;顶部的功能就像这样:

public function onKernelResponse(FilterResponseEvent $event)
{
    exit;

    // Don't do anything if it's not the master request.
    if (!$event->isMasterRequest()) {
        return;
    }
    ...

ResponseListener有什么问题吗?有没有一些配置可以在apache上完成,这个错误不会被抛出?

编辑:

这是MAMP PRO vhost配置:

<VirtualHost *:80>
ServerName project.localhost

DocumentRoot "/Users/MyUser/Projekte/MyProject/web"

<IfModule xsendfile_module>
    XSendFilePath "/Users/MyUser/Projekte/MyProject/web"
</IfModule>

<Directory "/Users/MyUser/Projekte/MyProject/web">
    Options Includes FollowSymLinks ExecCGI
    AllowOverride All
    <IfModule authz_host_module>
        Order allow,deny
        Allow from all
    </IfModule>

</Directory>

WSGIDaemonProcess project.localhost processes=2 threads=15
WSGIProcessGroup project.localhost
WSGIScriptAlias /project.localhostWsgiApp "/Users/MyUser/Projekte/MyProject/web/wsgiapp.py"
AddHandler PHP-fastcgi .PHP
Action PHP-fastcgi "/fcgi-bin/PHP7.0.13.fcgi"

编辑2:

根据@mickadoo的建议,另一个监听器可能会添加重复的头Content-Type.如果我停止传播,我得到我想要的Symfony错误消息.但是我的听众也是第一个被调用的,所以这将阻止任何其他监听器被触发.执行debug:event-dispatcher会导致以下结果:

"kernel.response" event
-----------------------

 ------- -------------------------------------------------------------------------------------------- ----------
Order   Callable                                                                                     Priority
 ------- -------------------------------------------------------------------------------------------- ----------
  #1      MyCompany\Bundle\AppBundle\EventListener\ResponseListener::onKernelResponse()                   0
  #2      Sonata\BlockBundle\Cache\HttpCacheHandler::onKernelResponse()                                0
  #3      Symfony\Component\HttpKernel\EventListener\ResponseListener::onKernelResponse()              0
  #4      Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector::onKernelResponse()        0
  #5      Symfony\Component\Security\Http\RememberMe\ResponseListener::onKernelResponse()              0
  #6      Sensio\Bundle\FrameworkExtraBundle\EventListener\HttpCacheListener::onKernelResponse()       0
  #7      Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelResponse()              -100
  #8      Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener::onKernelResponse()   -128
  #9      Symfony\Component\HttpKernel\EventListener\SaveSessionListener::onKernelResponse()           -1000
  #10     Symfony\Component\HttpKernel\EventListener\StreamedResponseListener::onKernelResponse()      -1024
 ------- -------------------------------------------------------------------------------------------- --------

当我添加另一个响应侦听器,优先级为-2048,使他成为最后一个触发,并使用以下方法

/**
 * @param FilterResponseEvent $event Filter response event
 */
public function onKernelResponse(FilterResponseEvent $event)
{
    // Don't do anything if it's not the master request.
    if (!$event->isMasterRequest()) {
        return;
    }

    $response = $event->getResponse();

    echo "<pre>";
    print_r($response->headers->all());
    exit;
}

它返回:

Array
(
    [cache-control] => Array
    (
        [0] => no-cache,private
    )
    [access-control-allow-origin] => Array
    (
        [0] => *
    )
    [access-control-allow-credentials] => Array
    (
        [0] => 1
    )
    [access-control-allow-headers] => Array
    (
        [0] => Origin,Authorization
    )
    [access-control-allow-methods] => Array
    (
        [0] => POST,PUT
    )
    [content-type] => Array
    (
        [0] => text/html; charset=UTF-8
    )
    [x-debug-token] => Array
    (
        [0] => 2f5dbb
    )
    [x-debug-token-link] => Array
    (
        [0] => http://app.project.localhost/app_dev.PHP/_profiler/2f5dbb
    )
)

但是还没有其他的Content-Type.有任何想法吗?

编辑3:

另一个奇怪的事情是:

如果我使用我的方法结尾处的$event-> stopPropagation(),并添加优先级为0的侦听器,所有的工作(意味着显示Symfony错误页面),如果我将其设置为优先级为-2048我得到了Apache错误信息.但是即使我输出的所有头都没有重复的头.我真的不知道这是怎么可能的.只需一个请求就可以将多个相同的标题返回给apache,而在结尾的所有标题输出中是唯一的?

如何设置事件的响应?

我的意思是根据$event-> getResponse()给出的响应,您添加标题,但是在else部分没有$event-> setResponse($response).

猜你在找的PHP相关文章