Laravel 4总是返回HTTP状态码200。

5

我在error.php中有以下代码,它是由我的控制器使用App::abort(404, $error)触发的。然而,我的响应状态代码仍然是200(正常)。我尝试了各种错误代码,如400、403。

// NotFoundException handler
App::error(function(NotFoundException $e)
{
    $default_message = 'The requested resource was not found';

    return Response::json(array(
        'error' => $e->getMessage() ?: $default_message,
    ), 404);
 });

你是否收到了JSON消息,指示这个错误是否实际上被触发了? - David Barker
是的,我正在以JSON格式获取实际的错误消息。我正在从响应中解析状态码并在视图中显示消息。 - Saravana Kumar
这更像是一个应该提交到Github上的bug报告。您肯定没有问任何问题! - Phill Sparks
最初它可以从控制器和error.php中工作。但在某个时候它停止了工作。 - Saravana Kumar
6个回答

9

对于任何仍在谷歌搜索此问题的人:

我为此问题苦苦挣扎了数小时。对我来说,问题是由一个控制器出现问题引起的。

检查所有控制器,确保在<?php标记前面没有空格。<?php标记应该是文件中的第一件事。如果您的控制器被路由到这样的位置,则在<?php标记前面有单个空格:

Route::controller('example', 'ExampleController');

会导致所有的状态码都变成200。

3
我已检查了所有控制器...仍然遇到这个问题。 - Adamski

7
我认为无论如何,你都应该收到404响应,所以可能还有其他问题导致你的代码无法正常运行。
也就是说,当出现404错误时,抛出的异常类是NotFoundHttpException而不是NotFoundException
由于Laravel 4使用Symfony的HttpKernal,因此这个异常在这里
当触发了404时,你可以在这里看到 App::abort()会抛出NotFoundHttpException
因此,你的代码应该像这样:
// NotFoundHttpException handler
App::error(function(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException $e)
{
    $default_message = 'The requested resource was not found';

    return Response::json(array(
        'error' => $e->getMessage() ?: $default_message,
    ), 404);
 });

重要提示:这只会在404错误状态下触发,因为它是对应于NotFoundHttpException的代码。其他状态码会返回其他异常类。要捕获所有HTTP状态错误码异常,请像这样对HttpException进行类型提示:

// HttpException handler
App::error(function(\Symfony\Component\HttpKernel\Exception\HttpException $e)
{
    return Response::json(array(
        'error' => $e->getMessage(),
    ), $e-> getStatusCode());
 });

最后,考虑在决定返回JSON或HTML时使用一些内容协商。请参考此处

我不得不使用完整的名称\Symfony\Component\HttpKernel\Exception\HttpException,否则它会出现致命错误“类HttpException不存在”。 - SlimDeluxe
哦,完全没问题 - 抱歉我应该指出来的。我会编辑答案把它加进去。 - fideloper
只是顺便提一下,App::error() 会传递异常对象和状态码 App::error(function(Exception $exception, $code),因此如果需要,您可以使用 $code 而不是 $exception->getStatusCode() - Ben Swinburne

2

这个解决方案对我没有用,所以如果还有人在寻找答案,我认为最好将其放在这里而不是创建另一个问题。

过了一段时间,我也遇到了这个问题,在我的app/Exceptions/Handler.php文件中有以下内容:

    if ($e instanceof ModelNotFoundException) {
        if ($request->ajax()) {
            return response()
                ->json(['error' => ['No results']])
                ->header('status', 422);
        }
    }

这在我的本地环境中可以运行,但是在模拟生产环境的同步环境中,它没有返回正确的状态码。

再仔细看了一下,我开始查看Laravel的文档,并将调用更改为以下内容:

    return response()
        ->json(['error' => ['No results.']], 422);

这样做就可以了。希望能对您有所帮助。


0
在我的情况下,我发现在

2
我认为你实际上正在尝试回答。请详细说明并解释你的观察如何帮助提问者解决问题。你可以[编辑]你的帖子以添加信息。 - Yunnosch

0

移除dump和其他打印函数

我正在积极调试时注意到了这个问题。这是因为在那时我的代码中有dump(...)的调用引起的。

当我移除了所有的调试dump调用后,状态码再次正确地是404(使用abort(404))。


0

我刚刚花了两天时间尝试解决一个类似的问题:无论我尝试发送什么头部或状态码与服务器响应,我总是会得到一个状态码为200的默认内容类型为text/html的响应。Laravel Sanctum的csrf-cookie也无法正常工作。

我的问题是由于一个 Laravel 配置文件顶部的换行符引起的。

示例代码:

` 
  //<--- \n
<?php

return [
    ...
];

`

为了找到罪魁祸首文件,在vscode中,我对项目的所有文件使用了正则表达式搜索:\n+(<?php)

knews12的原始答案非常有用,解决了我的问题,谢谢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接