继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

用yii2实现youtube风格的错误处理页面

abei2017
关注TA
已关注
手记 33
粉丝 1万
获赞 234

最近yii2开发组成员Alexander Makarov写了一篇blog,关于youtube网站报错信息页面的分析。

当我们的程序在生产阶段的时候,不能将程序的信息暴露出来,这会给黑客破解网站的机会。youtube网站则使用了一种算法对报错信息进行加密,这样开发人员就能通过解密程序及时获得程序到底出了什么问题?

blog链接:https://en.rmcreative.ru/blog/youtubes-500-error-page/

而Alexander Makarov也说到在yii2中通过使用errorHander和encryptByKey方法能实现同样的目的,今天就将yii2对此实现写一篇教程,希望对你有用。

当然,我的新版网站也使用了此方法 可以通过 https://nai8.me/forum/detail.html?id=abc 看到效果。

errorHandler

要实现上面目的需要对web.php的errorHandler进行配置,我们设置了自己的error报错视图,代码如下

'errorHandler' => [
    'errorAction' => 'site/error',
],

这个配置在components中,yii2默认即配置如此,所以一般你不需要更改。

视图

因为上面指定了errorAction = site/error,因此对应的视图就是site/view.php,这就是我们将来要编写错误显示的页面。

All Error

我们知道针对于每个url,yii2框架会将其解析到对应控制器的action上,因此我们需要对每个控制器设置其error动作,在这里有一个小方法,你可以抽象出一个父类让所有的控制器继承它,然后在父类中进行error动作的指定即可。

代码如下

public function actions() {
    return [
        'error' => [
            'class' => 'yii\web\ErrorAction',
            'layout' => 'empty'
        ],
    ];
}

是的,我们重写了控制器的actions方法,含义是当出现error动作的时候由yii2的 yii\web\ErrorAction 接管,也就是说我们site/error.php视图是由yii\web\ErrorAction进行操作和传值的。

为了显示方法我们还通过 'layout' => 'empty' 设置了site/error.php视图自己的布局,如果不设置则使用yii2默认的。

传值

现在我们知道对于每个控制器的动作,发生问题的时候都会由 yii\web\ErrorAction 并将结果渲染到site/error.php视图内,用户看到结果。

现在我们看看 yii\web\ErrorAction 都为 site/error.php视图 传递了什么?

// /vendor/yiisoft/yii2/web/ErrorAction.php
protected function getViewRenderParams()
{
    return [
        'name' => $this->getExceptionName(),
        'message' => $this->getExceptionMessage(),
        'exception' => $this->exception,
    ];
}

在这里我们看到可以使用 name / message / exception三个变量,它们的含义如下

  • name 报错名字(比如404等)
  • message 简单信息,一般会显示服务器错误等简短信息
  • exception 错误对象,此错误的所有数据。

因此我在视图内进行了如下编码

<div class="site-error">
    <h1>报错啦~</h1>

    <div class="message">
        <?= nl2br(Html::encode($message)) ?>
    </div>

    <div class="detail">
        <strong>报错信息:</strong>
        <?= $exception->getMessage();?>
    </div>
</div>

但是这样会有问题,$exception->getMessage() 将错误的关键信息显示出来,对我们开发者是有用的,但是用户也看到了。

因此我们要对其进行加密,在这里使用 Alexander Makarov 说的encryptByKey方法,此方法需要一个key,然后对数据进行加密,对于加密后的结果我们可以使用 decryptByKey 进行解密。

encryptByKey

好了,那就开始加密吧,yii2内置已经提供了,简单使用一下。

<?= Yii::$app->security->encryptByKey($exception->getMessage(),'abc');?>

ok,这样你就能看到下面截图的结果,这样我们在生产环境中也能及时获得某个页面为何出错了~

图片描述

打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP