通过某些路由前缀 [Laravel] 捕获未找到错误


Catch not found error by certain route prefix [Laravel]

我正在 laravel 5.2 中与网站一起构建 web api,当用户像http://stage.dev/unavailable/link一样访问我的网络上不可用的 url 时,它会在错误视图资源上的 404 页面上抛出,然后我想用不同的方式捕获如果用户尝试使用不可用的 url(如 http//stage.dev/api/v1/unavailable/link(访问我的 API,那么我想返回json/xml响应

{
  'status' : 'not found',
  'code' : 404,
  'data' : []
}

不是视图,有没有办法通过 url 前缀"api/*"或如何检测它..,也许是另一种具有类似结果的方法,因此访问它的设备/客户端可以通过标准格式进行(我在所有 JSON 响应中都有简单的格式(

{
  'status' : 'success|failed|restrict|...',
  'api_id' : '...',
  'token' : '...',
  'data' : [
    {'...' : '...'},
    {'...' : '...'},
    ...
  ]
}

解决

在阅读克里斯和阿列克谢的答案后,我想出了一些东西,这种方法对我有用,我在render()方法handler.php中添加了几行,

    if($e instanceof ModelNotFoundException || $this->isHttpException($e)) {
        if($request->segment(1) == 'api' || $request->ajax()){
            $e = new NotFoundHttpException($e->getMessage(), $e);
            $result = collect([
                'request_id' => uniqid(),
                'status' => $e->getStatusCode(),
                'timestamp' => Carbon::now(),
            ]);
            return response($result, $e->getStatusCode());
        }
    }

我的标头请求响应 404 错误代码并像我想要的那样返回 JSON 数据。

也许有更好的方法可以做到这一点,但您可以创建自定义错误 404 处理程序。按照本教程进行操作,但case 404部分更改为如下所示的内容:

if(str_contains(Request::url(), 'api/v1/')){
    return response()->json(your_json_data_here);
}else{
    return 'Response::view('custom.404',array(),404);
}

App'Exception'Handler.php里面,你有一个render的方法,可以方便地用于通用的错误捕获和处理。

在这种情况下,您还可以使用 request()->ajax() 方法来确定它是否为 ajax。它通过检查某些标头是否存在来实现此目的,特别是:

'XMLHttpRequest' == $this->headers->get('X-Requested-With')

无论如何,回到Handler.php中的渲染方法。

您可以执行以下操作:

public function render($request, Exception $e)
{        
    if($e instanceof HttpException && $e->getStatusCode() == 404) {
        if (request()->ajax()) {
            return response()->json(['bla' => 'foo']);
        } else {
            return response()->view('le-404');
        }
    }
    return parent::render($request, $e);
}

我在阅读克里斯阿列克谢的答案后想出了一些东西,这种方法对我有用,我在处理程序中添加了几行.php 在 render(( 方法,,

    if($e instanceof ModelNotFoundException || $this->isHttpException($e)) {
        if($request->segment(1) == 'api' || $request->ajax()){
            $e = new NotFoundHttpException($e->getMessage(), $e);
            $result = collect([
                'request_id' => uniqid(),
                'status' => $e->getStatusCode(),
                'timestamp' => Carbon::now(),
            ]);
            return response($result, $e->getStatusCode());
        }
    }