首页 > 解决方案 > 如何在 json 中强制做出安静的响应?

问题描述

我想向我的 Yii2 站点添加一些 api。Api 必须仅在 json 中。我不想Accept: application/json为每个请求设置标头。我可以 'response' => ['format' => \yii\web\Response::FORMAT_JSON]在应用程序配置中进行设置,但它会破坏所有页面。我的 api 函数也以 xml 格式返回数据。

我试图将其rest\ActiveRecord用于我的目的。也许我这样做是错误的。我想要的是。

让我的基于 Yii2 的站点通过https://example.com/api/controller/action. 在项目中,我想查看controllers/api包含我的控制器的文件夹。控制器必须使用基于标准\yii\db\ActiveRecord的模型。此外,控制器仅在 json 正文中或作为部分 url 输入参数,并仅在 json 中输出数据。

标签: yii2

解决方案


更优雅的解决方案是使用yii\filters\ContentNegotiator. 当Accept标头丢失时,假定它允许任何类型并以其属性ContentNegotiator中定义的第一种格式发送响应。$formats如果请求的格式不在接受的格式中,内容协商器将抛出yii\web\NotAcceptableHttpException并且应用程序将以 http status 响应406 Not Acceptable

您可以使用behaviors()以下方法将其添加到控制器中:

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\ContentNegotiator',
            'formats' => [
                'application/json' => \yii\web\Response::FORMAT_JSON,
            ],
        ],
    ];
}

如果您的控制器扩展yii\rest\Controller它已经ContentNegotiator在其行为中添加了过滤器。您只需要限制允许的格式,如下所示:

public function behaviors()
{
    $behaviors = parent::behaviors();
    $behaviors['contentNegotiator']['formats'] = [
        'application/json' => \yii\web\Response::FORMAT_JSON,
    ];
    return $behaviors;
}

如果将来需要,使用ContentNegotiator而不是显式强制JSON格式将允许更轻松地添加其他格式。beforeAction()


推荐阅读