【问题标题】:How would you handle different error responses for different routes using Laravel你将如何使用 Laravel 处理不同路由的不同错误响应
【发布时间】:2014-12-22 03:28:50
【问题描述】:

我设置了 Laravel 路由,如下例所示:

Route::group(array('domain' => 'example.com'), function()
{
    Route::get('/', array('as' => 'root.index', 'uses' => 'RootController@Index'));
    [...]
});

Route::group(array('domain' => 'api.example.com'), function()
{
    Route::when('*', 'ApiFilter');
    Route::get('/', array('as' => 'api.index', 'uses' => 'ApiController@Index'));
    [...]
});

现在,当涉及到响应有错误的请求(例如 404、403、500 等)时,Laravel 使用 App::error 及其相关方法提供了一个很好的解决方案。

我想根据请求是针对根域还是 api 域来以不同方式响应错误。

我可以使用App::error 执行此操作吗?

希望这是有道理的。

谢谢

【问题讨论】:

    标签: php laravel laravel-4


    【解决方案1】:

    是的,您可以这样做。只需要从异常处理程序中的$exception对象中获取请求对象,例如,如果你有这样的异常处理程序:

    App::error(function(Exception $exception, $code)
    {
        $request = $exception->getTrace()[0]['args'][0];
        $path = $request->path(); // will return path without domain, i.e. user/1
        // Take some action depending on the $path
    });
    

    现在根据路径,您可以采取行动。您可以使用Request 类的任何公共方法,例如if($request->is('admin/*'))$request->url() 来获取带域的完整url。

    【讨论】:

      【解决方案2】:

      您还可以对不同的错误格式使用内容协商(Accept 请求标头或以.json / .xml 为后缀的 URL),如下所示:

      App::error(function(Exception $exception, $code)
      {
          if (!preg_match("@text/html@", Request::header('Accept')))
          {
              return Response::json
              (
                  array("error" => array("message" => $exception->getMessage())),
                  $code
              );
          }
      });
      

      如果请求标头 Accept 不包含 text/html,这将导致错误以 JSON 形式返回。

      所以.. 如果您使用浏览器访问 api.yoursite.com - 您仍然会看到带有堆栈跟踪和完整详细信息的默认 HTML 错误页面,因为浏览器将发送 Accept: text/html

      否则,如果 Accept 标头未设置或未明确包含 text/html - 错误将被格式化为 JSON。

      或者,您可以使用Request::wantsJson() 代替preg_match 来检测请求的内容格式。

      或者,如果您绝对需要/想要分离 API 逻辑并通过子域路由..:

      App::error(function(Exception $exception, $code)
      {
          if (preg_match("@^https?://api\.@", Request::url())) /* Or, if not using sub-domain: Request:is("api/*") */
          {
              return Response::json
              (
                  array("error" => array("message" => $exception->getMessage())),
                  $code
              );
          }
      });
      

      【讨论】:

        【解决方案3】:

        我会对每个路由组应用单独的过滤器,然后在每个过滤器中指定错误处理事件。

        【讨论】:

        • 你有一个如何将错误处理程序应用于路由组的示例吗?
        猜你喜欢
        • 2021-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 2020-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多