Zend Framework:如何处理Ajax请求中的异常?

时间:2010-06-01 06:47:00

标签: php ajax zend-framework error-handling

通常在抛出异常时,错误控制器会接受命令并显示带有常规页眉和页脚的错误页面。

在Ajax请求中不需要此行为。因为如果出错,整个html页面都会被发送出去。如果我直接在div中加载http响应的内容,这甚至更不需要。

相反,在Ajax请求的情况下,我只想接收异常抛出的“实际错误”。

我该怎么做?

我认为,一种肮脏的方式可能是:在ajax请求中设置var并相应地处理。不是一个好的解决方案。

3 个答案:

答案 0 :(得分:2)

如果您使用contextSwitchajaxContext操作帮助程序对错误进行编码(可能会关闭autoJsonSerialization),您只需将错误作为JSON / XML对象传回。

http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#zend.controller.actionhelpers.contextswitch

class Error_Controller extends Zend_Controller{
    public function errorAction(){
        $contextSwitch = $this->_helper->getHelper('contextSwitch');
        $contextSwitch->addActionContext($this->getRequest()->getActionName(),'json')
            ->initContext();
        $errors = $this->_getParam('error_handler');
        $this->view->exception = $errors->exception;
    }
}

从那里你必须传递一个format = json参数,每个AJAX请求或设置一个自动附加它的路由链。

对于'稍微'更安全的设置,您可以使用ajaxContext作为帮助程序,只有XMLHttpRequest标头的请求才会被提供给json。

答案 1 :(得分:1)

我使用的代码保留了非Ajax请求的错误处理,同时保持'displayExceptions'选项不变。它与常规错误处理程序完全相同,因为当“displayExceptions”在 application.ini 文件中处于活动状态时,堆栈跟踪和请求参数也会被发回。发送回JSON数据有很多灵活性 - 您可以创建自定义类,使用带有JSON视图助手的视图等。

class ErrorController extends Zend_Controller_Action
{
    public function errorAction()
    {
        $errors = $this->_getParam('error_handler');

        if ($this->getRequest()->isXmlHttpRequest()) {
            $this->_helper->contextSwitch()->initJsonContext();

            $response = array('success' => false);

            if ($this->getInvokeArg('displayExceptions') == true) {
                // Add exception error message
                $response['exception'] = $errors->exception->getMessage();

                // Send stack trace
                $response['trace'] = $errors->exception->getTrace();

                // Send request params
                $response['request'] = $this->getRequest()->getParams();
            }

            echo Zend_Json::encode($response);
            return;
        }

        switch ($errors->type) {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:

                // 404 error -- controller or action not found
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->message = 'Page not found';
                break;
            default:
                // application error
                $this->getResponse()->setHttpResponseCode(500);
                $this->view->message = 'Application error';
                break;
        }

        // conditionally display exceptions
        if ($this->getInvokeArg('displayExceptions') == true) {
            $this->view->exception = $errors->exception;
        }

        $this->view->request = $errors->request;
    }
}

答案 2 :(得分:1)

我玩过两个先前的答案,但一直遇到问题。有几个原因我遇到了麻烦,其中一个原因是我希望能够在事情进展顺利时从常规控制器返回原始HTML。

这是我最终提出的解决方案:

class ErrorController extends Zend_Controller_Action
{
    public function init()
    {
        // Add the context to the error action
        $this->_helper->contextSwitch()->addActionContext('error', 'json');
    }

    public function errorAction()
    {
        // Check if this is an Ajax request
        if ($this->getRequest()->isXmlHttpRequest()) {

            // Force to use the JSON context, which will disable the layout.
            $this->_helper->contextSwitch()->initContext('json');

            //   Note: Using the 'json' parameter is required here unless you are
            //   passing '/format/json' as part of your URL.
        }

        // ... standard ErrorController code, cont'd ...