Slim3如何管理混合内容类型错误

时间:2019-06-21 11:00:58

标签: http-headers content-type slim-3

我需要为html和json内容设置一个Slim应用程序。 我将只有一个错误处理程序,应该以json的形式回复json,并以html的html错误页面作为视图。 在旧的衰落的Slim(v.2)中,我已经在路线开始处定义了视图,因此我可以检查视图类型(twig或json)以了解如何回复。

使用新的Slim3实现,该视图将在路由的末尾发送,据我所知,无法提前定义它。

如何处理这种混合内容错误?

我曾考虑使用请求内容类型标头,但没有一个真正的规则,即内容类型应与响应保持一致,例如,我可以将某些请求作为application / json发送并获得text / html答复,我也不能使用Accept标头,因为它可能丢失或通用的*/*

1 个答案:

答案 0 :(得分:0)

我想这取决于您如何决定返回json格式还是html。

例如,当AJAX请求时,您可能会以json格式返回错误,否则返回html。

如果您的错误处理程序会返回html,如以下代码所示

    var flag = 0;
    if(await DoSomeAsyncToKillsomeTimeAsync()>1)
    {
        flag=1;
    }

    if(flag==1)
        Console.WriteLine("if async op completed on time");
    else
        Console.WriteLine("actually this should be never hit as flag should be 1 but it seems this got hit before async op completed");

和返回json的错误处理程序,

<?php namespace Your\App\Name\Space\Errors;

class HtmlErrorHandler
{

    public function __invoke($request, $response, $exception)
    {
        $err = '<html><head></head><body>' .
            '<div>code : ' . $exception->getCode() . 
            ' message' . $exception->getMessage() '</div>';
        return $response->withStatus(500)
            ->withHeader('content-Type : text/html')
            ->write($err);
    }
}

您可以将它们组合在另一个错误处理程序类中,该类根据是否来自AJAX的请求选择要返回错误响应的错误处理程序。

<?php namespace Your\App\Name\Space\Errors;

class JsonErrorHandler
{    
    public function __invoke($request, $response, $exception)
    {
        $err = (object) [
            'code' => $exception->getCode(),
            'message' => $exception->getMessage(),
        ];
        return $response->withStatus(500)->withJson($err);
    }
}

或者您可以在查询字符串中放入某些变量以指示客户端所需的格式,然后可以使用

<?php namespace Your\App\Name\Space\Errors;

class Http500Error
{
    private $jsonErrorHandler;
    private $htmlErrorHandler;

    public function __construct($jsonErrHandler, $htmlErrHandler) 
    {
        $this->jsonErrorHandler = $jsonErrHandler;
        $this->htmlErrorHandler = $htmlErrHandler;
    }

    public function __invoke($request, $response, $exception)
    {
        if ($request->isXhr()) {
            $errHandler = $this->jsonErrorHandler;
        } else {
            $errHandler = $this->htmlErrorHandler;        
        }
        return $errHandler($request, $response, $exception);
    }
}

然后将错误处理程序注入容器

if ($request->getParam('format', 'html') === 'json') {
    $errHandler = $this->jsonErrorHandler;
} else {
    $errHandler = $this->htmlErrorHandler;        
}