首先,官方不觉得这是一个问题
代码语言:javascript复制如果在传统 HTTP 请求期间验证失败,则会生成对先前 URL 的重定向响应。如果传入的请求是 XHR,将将返回包含验证错误信息的 JSON 响应。
https://learnku.com/docs/laravel/9.x/validation/12219#quick-writing-the-validation-logic
问题复现
代码语言:javascript复制cuiwei@weideMacBook-Pro ~ % curl -X POST 'http://laravel.cw.net/api/login'
--header 'Content-Type: application/json'
--data '{
"email1": "11@qq.com",
"password": "a"
}'
...
Redirecting to <a href="http://laravel.cw.net">http://laravel.cw.net</a>.
</body>
</html>
如上,一个正常的请求,因为参数错误,跳首页去了。。
按照官方的说法,模拟 XHR 请求,即增加 header 头X-Requested-With: XMLHttpRequest
cuiwei@weideMacBook-Pro ~ % curl -X POST 'http://laravel.cw.net/api/login'
--header 'Content-Type: application/json'
--header 'X-Requested-With: XMLHttpRequest'
--data '{
"email1": "11@qq.com",
"password": "a"
}'
{"message":"The email field is required.","errors":{"email":["The email field is required."]}}
这下符合预期了。如果这个项目只是前端对接,默认就是ajax请求,很合理。
但我这个项目有 Android
端 和 iOS
端,让他们额外加这么一个参数就不合适了。
解决方案
方案1
重写 failedValidation
方法
<?php
namespace AppHttpRequests;
use IlluminateContractsValidationValidator;
use IlluminateFoundationHttpFormRequest;
use IlluminateHttpExceptionsHttpResponseException;
class BaseRequests extends FormRequest
{
/**
* validate验证失败模板
* @param Validator $validator
*/
protected function failedValidation(Validator $validator)
{
$message = '';
foreach (json_decode(json_encode($validator->errors()),1) as $error){
$message = $error[0];
break;
}
throw (new HttpResponseException(response()->json([
'code' => 400,
'msg' => $message,
'data' => []
])));
}
}
https://blog.csdn.net/woshissss/article/details/120397036
方案2
方案1我没试,借鉴网上的。重点是方案2
拦截ValidationException
异常
<?php
namespace AppExceptions;
class Handler extends ExceptionHandler
{
public function render($request, Throwable $e)
{
if ($e instanceof ValidationException) {
//errorValidate为自定义的统一输出,重点是你拿到了$e
return $this->errorValidate($e->errors(), $e->getCode(), $e->getMessage());
}
//其他异常
if ($e instanceof NotFoundHttpException) {
return $this->errorNotFound();
}
return $this->error(new ArrayObject(), $e->getCode() ?: 400, $e->getMessage());
}
}