php - CakePHP 中的 Ajax 错误处理

标签 php ajax cakephp error-handling

我想做一些与 this 非常相似的事情但在 CakePHP 世界中用于 AJAX 请求。目前我正在这样做:

$this->autoRender = false;
$this->response->statusCode(500);

它基于 this .但是,此解决方案不允许我像 Rails 示例中那样包含自定义消息,因此,在我的客户端错误处理程序中,我可以显示包含在 500 错误响应中的消息。

我如何在 CakePHP 中实现与 Ruby on Rails 示例相同的功能?

最佳答案

如上所述,异常是在 CakePHP 中返回 AJAX 请求错误的方式。这是我的解决方案,用于更好地控制错误的外观。另外,如上所述,我使用的是自定义异常渲染器,但不是自定义异常。默认的错误响应是一个像这样的 JSON 对象:

{"name":"An Internal Error Has Occurred", "url": "\/users\/login.json"}

几乎喜欢默认渲染器处理 AJAX 错误的方式;我只想稍微调整一下:

<?php
// File: /app/Lib/Error/CustomExceptionRenderer.php
App::uses('ExceptionRenderer', 'Error');
class CustomExceptionRenderer extends ExceptionRenderer {

    // override
    public function error400($error) {
        $this->_prepareView($error, 'Not Found');
        $this->controller->response->statusCode($error->getCode());

        $this->_outputMessage('error400');
    }

    // override
    public function error500($error) {
        $this->_prepareView($error, 'An Internal Error Has Ocurred.');
        $code = ($error->getCode() > 500 && $error->getCode() < 506) ? $error->getCode() : 500;
        $this->controller->response->statusCode($code);

        $this->_outputMessage('error500');
    }

    private function _prepareView($error, $genericMessage) {
        $message = $error->getMessage();
        if(!Configure::read('debug') && !Configure::read('detailed_exceptions')) {
            $message = __d('cake', $genericMessage);
        }
        $url = $this->controller->request->here();
        $renderVars = array(
            'name' => h($message),
            'url' => h($url),
            );
        if(isset($this->controller->viewVars['csrf_token'])) {
            $renderVars['csrf_token'] = $this->controller->viewVars['csrf_token'];
        }
        $renderVars['_serialize'] = array_keys($renderVars);
        $this->controller->set($renderVars);
    }
}

然后,在 bootstrap.php 中:

Configure::write('Exception.renderer', 'CustomExceptionRenderer');

下面是它的工作原理:

  • 假设我想在我的错误响应中返回一个新的 CSRF token ,这样如果我现有的 token 在异常被抛出之前已经过期,我下次尝试请求时就不会被黑洞。查看Security Component documentation有关 CSRF 保护的更多信息。
  • 在 app/Lib/Error 中创建一个新类。您可以扩展默认渲染器,也可以不扩展。由于我只想更改一些小东西,并使示例保持简单,因此我对其进行了扩展。
  • 覆盖默认呈现器用于创建将返回的 JSON 对象的方法。这是通过 Request Handler Component 完成的,并符合最佳实践。事实上,默认渲染器做同样的事情。
  • 新的私有(private)方法让事情保持干爽。
  • 我对在生产中没有收到自定义错误消息的问题的解决方案是添加一个可选的配置键。默认情况下,此类将在生产中显示通用消息,但如果您将调试设置为 0,并且您想要特定的错误消息:Configure::write('detailed_exceptions', 1);<
  • 将新 token 添加到响应中(如果存在)。就我而言,我已经在 AppController 的 beforeFilter 方法中对新 token 调用了 Controller::set,因此它在 $this->controller->viewVars 中可用.可能有许多其他方法可以实现此目的。

现在您的响应如下所示:

{
    "name":"The request has been black-holed",
    "url":"\/users\/login.json",
    "csrf_token":"1279f22f9148b6ff30467abaa06d83491c38e940"
}

任何类型的任何附加数据都可以添加到传递给 Controller::set 的数组中以获得相同的结果。

关于php - CakePHP 中的 Ajax 错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11585620/

相关文章:

mysql - 带条件的 Cakephp 模型

php - 无法在 PHP 中排序多维数组

php - 将数据从 PHP 表单发布到 File maker pro 12 服务器上的 File Maker 数据库

php - PHP Mysql从多个搜索框数组添加到购物车

php - Google map API 无法在 Bitrix 上使用 AJAX

javascript - 无法在聊天应用程序中使用 Ajax 调用从 Controller 返回 html

php - saveMany 验证无法正常工作

php - 如何以编程方式获取 SVN 修订号?

javascript - extjs ajax 调用存储未加载

mysql - Cakephp 查询数据库中的枚举字段