自定义错误页面和 json 响应格式 [ 2.0 版本 ]
想要自定义错误页面和json响应格式,但是不知道怎么配置。
'errorHandler' => [
'errorAction' => 'site/error',
],
site控制器下的 actions 方法中 error 也自己定义了返回的 错误类
public function actions()
{
return [
'error' => [
// 'class' => 'yii\web\ErrorAction',
'class' => 'backend\components\helper\ErrorAction',
]
];
}
<?php
namespace backend\components\helper;
use yii\web\ErrorAction as SystemErrorAction;
use yii\web\NotFoundHttpException;
class ErrorAction extends SystemErrorAction
{
protected function renderHtmlResponse()
{
if (\Yii::$app->user->isGuest) {
$this->controller->layout = false;
$this->view = 'no-login-error';
}
return $this->controller->render($this->view ?: $this->id, $this->getViewRenderParams());
}
}
故意输出错误的时候,会显示:An internal server error occurred.
问下怎么能够按照自己想要的错误格式去显示,ajax请求输出json格式。正常的网页请求显示我定义的错误界面。查了资料有的在基类控制器中修改。如果在配置文件中怎么去配置呢?
问题已经解决,
由于有请求我在控制器中没写 FORMAT_JSON ,用了重定向,配置AJAX请求如下:
'response' => [
'class' => 'yii\web\Response',
'on beforeSend' => function ($event) {
/* @var \yii\web\Response $response */
$response = $event->sender;
// 这里我们仅针对 ajax 请求
if ( (request()->isAjax && $response->statusCode == 500)) {
if($response->format != response()::FORMAT_JSON)
$response->format = response()::FORMAT_JSON;
// 手动将抛出异常的状态码改为 200, 确保不被 jQuery 捕获
$response->statusCode = 200;
// 自定义错误显示格式,把真正的响应数据存储在 'data' option 内
$response->data = [
'code' => 0,
'data' => '出错了!',
];
}
},
],
至于 An internal server error occurred. 这个错误是 yii\base\ErrorHandler 抛出的。这个错误很高级,故意配置错数据库,才会显示。在这个基础上在访问一个错的URL 会出现2次重复的这句话,也就是抓到了2次错误。在 yii\base\ErrorHandler类的handleFallbackExceptionMessage方法中 echo 1;exit;都会重复输出。set_exception_handler set_error_handler 这个2个函数搞的鬼。想定制一个抓取所有错误的界面简单点可以搞 web 服务器重定向了。问题过几天在关闭。大家一起讨论。
最佳答案
-
你代码中的配置仅对正常的网页请求,ajax 请求的个性化错误信息可通过配置
response
组件实现。你遇到的 500 错误是因为 response 组件在遇到错误时,直接把错误传递到客户端并被 jQuery 捕获。可以借助 Response 的 beforeSend 事件改变这种默认的行为:在发送错误前将错误信息进行封装,
'components' => [ 'response' => [ 'class' => 'yii\web\Response', 'on beforeSend' => function ($event) { $response = $event->sender; // 这里我们仅针对 ajax 请求 if ($response->format == \yii\web\Response::FORMAT_JSON) { if ($response->data !== null) { // 手动将抛出异常的状态码改为 200, 确保不被 jQuery 捕获 $response->statusCode = 200; // 自定义错误显示格式,把真正的响应数据存储在 'data' option 内 $response->data = [ 'success' => $response->isSuccessful, 'data' => $response->data, ]; } } }, ], ],
配置后,如果通过 ajax 访问下面的 action,
// in TestController.php public function actionAjaxRead() { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; // 这里将抛出异常 return 3/0; }
$.post("/test/ajax-read", function(response) { console.log(response) })
响应内容将输出:
参考: https://www.yiiframework.com/doc/guide/2.0/zh-cn/runtime-handling-errors#error-format
共 6 条回复@小叮当的肚兜 errorHandler 组件接管异常处理时,能捕获绝大部分异常,遇到不能识别的异常,才会调用 convertExceptionToArray() 处理。 https://github.com/yiisoft/yii2/blob/master/framework/web/ErrorHandler.php#L107-L132
"An internal server error occurred" 就是在这个方法内产生的 (https://github.com/yiisoft/yii2/blob/master/framework/web/ErrorHandler.php#L146)
你说的故意配错数据导致 500 错误出现我没能重现出来。如果故意把数据库密码输入错误,errorHandler 会捕获 yii\db\Exception:
这个异常是通过
site/error
通过 error 视图显示出来的nauhein 觉得很赞
其他 0 个回答
小叮当的肚兜
最后登录:8小时前
在线时长:97小时45分
- 粉丝13
- 金钱44030
- 威望270
- 积分47700