【问题标题】:404 Issue in Laravel API when required param value not passed未传递所需参数值时 Laravel API 中的 404 问题
【发布时间】:2017-06-16 06:08:22
【问题描述】:

请求类

class LoginRequest extends Request
{

    public function authorize() {
        return true;
    }

    public function rules() {
        return [
            'EmailAddress'  => 'required',
            'Password'      => 'required',
        ];
    }

    public function messages() {
        return [
            "EmailAddress.required" => trans("login.RequiredEmailAddress"),
            "Password.required"     => trans("login.RequiredPassword")
        ];
    }
}

路线

Route::post('/AuthenticateUser', 
    array(
        'uses' =>  'API\Login\apiLoginController@AuthenticateUser', 
        'as'   =>  'AuthenticateUser'
    )
);

控制器动作方法

我有一个控制器,到目前为止,我对请求类所做的只是为了验证输入参数。下面是动作方法

public function AuthenticateUser(LoginRequest $request) {
    dd("Hello");
}

网址

localhost:85/Laravel/public/api/v1/AuthenticateUser

我正在使用 Postman Chrome 扩展程序来测试 Url。因此,我们可以看到,在 Request 类中,电子邮件地址和密码都是必需的参数。

当我传递两个参数值时。没有问题,一切正常。当我将电子邮件地址值保留为空时...出现 404 错误,这是屏幕截图。

如果没有提供电子邮件地址,我是否遗漏了一些东西来摆脱 404 错误?我期待输入电子邮件地址的错误消息

下面是我同时传递邮箱和密码时的工作状态

【问题讨论】:

  • 这很可能是因为您输入的 URI 不正确。 - 输入 php artisan route:list 以查看所有现有的 URI,并尝试它们。为什么还要包含 URI 的 Laravel/public 部分?您通常不需要添加它,并且您是否在路由文件中将前缀定义为api/v1
  • 正如我在问题中已经提到的,如果我同时传递电子邮件地址和密码,它就可以工作。
  • 我们缺少一些信息。你说如果你提供这两个字段,它就可以工作,但是你应该看到dd('hello')的结果,但是你得到的是JSON。您收到 404 的可能原因是因为在您的应用程序的某个地方,它正在您的数据库中搜索一个空的电子邮件地址,但没有找到任何东西。您需要找到输出 JSON 的正确控制器来解决问题。

标签: php laravel laravel-5.3


【解决方案1】:

解决方案 1:

我设法通过在请求中添加以下标头来摆脱 404 并返回 422:

accept:application/json

这并不是 Laravel 中真正的错误 Taylor pointed out 而是一种区分它是否是 AJAX/API 请求的方法。

解决方案 2:

或者,如果您不希望客户端指定该标头,您可以创建一个中间件,在每个 API 请求上添加标头 accept:application/json。方法如下:

  1. 新建中间件:app/Http/Middleware/ForceJsonResponse.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class ForceJsonResponse
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        $request->headers->set('Accept', 'application/json');

        return $next($request);
    }
}

  1. /app/Http/Kernel.php 中,在$middlewareGroups.api 中,为新创建的中间件指定命名空间:
    protected $middlewareGroups = [
        'web' => [...],
        'api' => [
            [...]
            \App\Http\Middleware\ForceJsonResponse::class,
        ],
    ];

【讨论】:

    【解决方案2】:

    终于通过如下更改请求类使其工作。

    class LoginRequest extends Request
    {
    
        public function wantsJson() {
            return true;
        }
    
        public function authorize() {
            return true;
        }
    
        public function rules() {
            return [
                'EmailAddress'  => 'required',
                'Password'      => 'required',
            ];
        }
    
        public function messages() {
            return [
                "EmailAddress.required" => trans("login.RequiredEmailAddress"),
                "Password.required"     => trans("login.RequiredPassword")
            ];
        }
    }
    

    刚刚添加了下面的代码。

    public function wantsJson() {
        return true;
    }
    

    【讨论】:

      【解决方案3】:

      这是因为您直接在路由处理上进行验证,而不是通过 NotFoundException 进行匹配。您需要按原样将请求传递给您的控制器并执行以下操作:

      $this->validate($request, [
                  'EmailAddress'  => 'required|email',
                  'Password'      => 'required',
              ]);
      

      【讨论】:

      • 我怀疑是不是因为这个,只是因为如果验证失败,Laravel 会返回 422 错误,而不是 404
      • 如果我同时传递电子邮件地址和密码,它就可以工作。但是当我将电子邮件地址值保留为空时不起作用。请检查有问题的屏幕截图
      • 它在验证失败时返回 422,但在路由上它不是验证,它是与 NotFoundException 又名状态 404 匹配的路由!!!感谢您投反对票,但最好先测试一下,然后投反对票@PhilCross
      • 我在投票中什么也没做。这个网站有数百万用户。我添加了更多有问题的屏幕截图。
      • 我写了404的原因,你可以在你的代码上测试
      猜你喜欢
      • 2021-03-22
      • 2017-03-08
      • 1970-01-01
      • 2017-10-21
      • 2021-06-26
      • 2020-08-07
      • 1970-01-01
      • 2020-09-10
      • 2021-07-14
      相关资源
      最近更新 更多