我想展示API和网站的不同响应。在api响应中,我想用404和500显示json响应,主要用于路由的异常类型。
如果用户尝试请求未找到的路线和路线,我想在网站的API和网页的json响应中显示响应。
我知道并将代码编入app/Exceptions/Handler.php
public function render($request, Exception $exception)
{
if ($exception instanceof NotFoundHttpException) {
if ($request->expectsJson()) {
return response()->json(['error' => 'Not Found'], 404);
}
return response()->view('404', [], 404);
}
return parent::render($request, $exception);
}
https://laravel.com/docs/5.4/errors#http-exceptions
但是失败的任何人都可以帮助我如何为错误页面设置不同的响应。
答案 0 :(得分:7)
期待JSON是关于标题的,我不喜欢API错误的解决方案,说实话,您可以通过浏览器访问它。大多数情况下,我的解决方案是按网址路由进行过滤,因为它通常以"api/..."
开头,可以这样做$request->is('api/*')
。
如果您有/ api路由,那么这将起作用,否则更改确定它是否是API路由的逻辑。
public function render($request, Exception $exception)
{
if ($exception instanceof NotFoundHttpException) {
if ($request->is('api/*')) {
return response()->json(['error' => 'Not Found'], 404);
}
return response()->view('404', [], 404);
}
return parent::render($request, $exception);
}
答案 1 :(得分:2)
只想为上述答案添加一个替代方法,这些方法似乎也都可以使用。
遇到相同的问题并深入研究之后,我采取了略有不同的方法:
您的异常句柄调用parent::render(...)
。如果您查看该函数,则如果您的请求指示wantsJson()
[请参见hints how that works here]
现在,要将所有响应(包括异常)转换为json,我使用了here中的Jsonify中间件思想,但将其应用于api MiddlewareGroup,该API默认情况下分配给RouteServiceProvider :: mapApiRoutes( )
这里是实现它的一种方法(非常类似于上面引用的答案):
创建文件app/Http/Middleware/Jsonify.php
<?php
namespace App\Http\Middleware;
use Closure;
class Jsonify
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ( $request->is('api/*') ) {
$request->headers->set('Accept', 'application/json');
}
return $next($request);
}
}
将中间件引用添加到app/Http/Kernel.php
文件的$ routeMiddleware表中:
protected $routeMiddleware = [
...
'jsonify' => \App\Http\Middleware\Jsonify::class,
...
];
在同一内核文件中,将jsonify名称添加到api组:
protected $middlewareGroups = [
...
'api' => [
'jsonify',
'throttle:60,1',
'bindings',
],
...
];
结果是为属于“ api”组的所有请求加载了中间件。如果请求url以api/
开头(我认为这有点多余),那么头将由Jsonify中间件添加。这将告诉ExceptionHandler :: render()我们想要一个json输出。
答案 2 :(得分:0)
我正在使用Laravel 5.5.28,并将其添加到app/Exceptions/Handler.php
public function render($request, Exception $exception)
{
// Give detailed stacktrace error info if APP_DEBUG is true in the .env
if ($request->wantsJson()) {
// Return reasonable response if trying to, for instance, delete nonexistent resource id.
if ($exception instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
return response()->json(['data' => 'Resource not found'], 404);
}
if ($_ENV['APP_DEBUG'] == 'false') {
return response()->json(['error' => 'Unknown error'], 400);
}
}
return parent::render($request, $exception);
}
预计您的API调用将包含一个包含密钥Accept
和值application/json
的标头。
然后,不存在的Web路由返回预期的
抱歉,找不到您要找的页面
且不存在的API资源返回JSON 404有效负载。
找到info here。
您可以将此与寻找NotFoundHttpException
实例的答案结合起来以捕获500.但我想,堆栈跟踪将是首选。
答案 3 :(得分:0)
无需费心去进行Laravel升级。您只需要在 routes / api.php
中定义此方法Route::fallback(function(){
return response()->json(['message' => 'Not Found!'], 404);
});
查看此链接以获取大部分为不良回答的回复Better 404 Responses
答案 4 :(得分:-1)
try this.
public function render($request, Exception $exception)
{
if ($request->ajax()) {
return \Response::json([
'success' => false,
'message' => $exception->getMessage(),
], $exception->getCode());
} else {
return parent::render($request, $exception);
}
}