我正在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', 'Origin, X-Requested-With, X-Auth-Token, X-App-Version, Content-Type, Accept, Authorization');
$response->headers->set('Access-Control-Allow-Methods', 'POST, GET, 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引起的,因为只要我在函数顶部放置exit;
就会显示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, X-Requested-With, X-Auth-Token, X-App-Version, Content-Type, Accept, Authorization
)
[access-control-allow-methods] => Array
(
[0] => POST, GET, 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,并且结尾的所有标头在输出中都是唯一的?
答案 0 :(得分:2)
如何设置对事件的响应?
我的意思是在$ event-&gt; getResponse()给出的响应中添加了标题,但是你不会在其他部分使用$ event-&gt; setResponse($ response)。