Chr*_*olb 11 php apache error-handling mamp symfony
我正在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');
}
}
Run Code Online (Sandbox Code Playgroud)
这只是在浏览器中开发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.
Run Code Online (Sandbox Code Playgroud)
如果我查看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
Run Code Online (Sandbox Code Playgroud)
这似乎只发生PHP错误.如果我例如抛出一个NotFoundHttpException带
throw new NotFoundHttpException("Test exception");
Run Code Online (Sandbox Code Playgroud)
我得到了通常的Symfony错误页面.
如果我做的事情
new ClassDoesNotExist();
Run Code Online (Sandbox Code Playgroud)
它导致内部服务器错误.
我知道这是由于ResponseListener,因为只要我exit;在函数的顶部放置了Symfony错误页面,就像这样:
public function onKernelResponse(FilterResponseEvent $event)
{
exit;
// Don't do anything if it's not the master request.
if (!$event->isMasterRequest()) {
return;
}
...
Run Code Online (Sandbox Code Playgroud)
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"
Run Code Online (Sandbox Code Playgroud)
编辑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
------- -------------------------------------------------------------------------------------------- --------
Run Code Online (Sandbox Code Playgroud)
当我添加另一个优先级为-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;
}
Run Code Online (Sandbox Code Playgroud)
它返回:
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
)
)
Run Code Online (Sandbox Code Playgroud)
但仍然没有额外的Content-Type.有任何想法吗?
编辑3:
另一件奇怪的事情如下:
如果我$event->stopPropagation()在我的方法的末尾使用并添加优先级为0的侦听器一切正常(意味着显示Symfony错误页面),如果我将其设置为优先级-2048,则会收到Apache错误消息.但即使我在其末尾输出所有标题,也没有重复的标题.我真的不明白这是怎么回事.如何只有一个请求将多个相同的标头返回到apache,并且结尾的所有标头在输出中都是唯一的?
小智 2
如何设置对事件的响应?
我的意思是在 $event->getResponse() 给出的响应上添加标头,但在其他部分上不添加 $event->setResponse($response) 。
| 归档时间: |
|
| 查看次数: |
761 次 |
| 最近记录: |