【问题标题】:Zend Framework: How to handle exceptions in Ajax requests?Zend Framework:如何处理 Ajax 请求中的异常?
【发布时间】:2011-02-26 05:26:09
【问题描述】:

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

在 Ajax 请求中不需要这种行为。因为在出错的情况下,整个 html 页面都会被发送过来。在我直接在 div 中加载 http 响应的内容的情况下,这更加不受欢迎。

如果是 Ajax 请求,我只想接收由异常引发的“实际错误”。

我该怎么做?

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

【问题讨论】:

    标签: php ajax zend-framework error-handling


    【解决方案1】:

    如果您使用 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;
        }
    }
    

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

    对于“稍微”更安全的设置,您可以使用 ajaxContext 作为您的助手,并且只有具有 XMLHttpRequest 标头的请求才会以 json 格式提供。

    【讨论】:

    • 能否提供 JSON 的代码 sn-p?那真的很有帮助。谢谢。
    【解决方案2】:

    我玩过之前的两个答案,但一直遇到问题。我遇到麻烦的原因有几个,其中之一是我希望能够在一切顺利时从常规控制器返回原始 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 ...
    

    【讨论】:

      【解决方案3】:

      我使用的代码保留了对非 Ajax 请求的错误处理,同时保持 'displayExceptions' 选项不变。它与常规错误处理程序完全一样,因为当 application.ini 文件中的 'displayExceptions' 处于活动状态时,堆栈跟踪和请求参数也会被发回。在发回 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;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-10-31
        • 1970-01-01
        • 2021-08-31
        • 2019-10-19
        • 1970-01-01
        • 2015-06-18
        相关资源
        最近更新 更多