我需要为html和json内容设置一个Slim应用程序。 我将只有一个错误处理程序,应该以json的形式回复json,并以html的html错误页面作为视图。 在旧的衰落的Slim(v.2)中,我已经在路线开始处定义了视图,因此我可以检查视图类型(twig或json)以了解如何回复。
使用新的Slim3实现,该视图将在路由的末尾发送,据我所知,无法提前定义它。
如何处理这种混合内容错误?
我曾考虑使用请求内容类型标头,但没有一个真正的规则,即内容类型应与响应保持一致,例如,我可以将某些请求作为application / json发送并获得text / html答复,我也不能使用Accept标头,因为它可能丢失或通用的*/*
。
答案 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;
}