我了解如何通过在控制器方法中键入提示类名来验证请求。然而,对于Ajax请求,根据文档,我应该验证控制器中的数据,因为使用验证器类会重定向而不是发送响应。
我看到的主要部分是:
如果传入的请求是AJAX请求,则不会重定向生成。相反,具有422状态代码的HTTP响应将是返回到浏览器,其中包含验证错误的JSON表示。
然而,我的控制器如下:
public function update(App'Permission $permission, Request $request)
{
$this->validate($request, [
'permission_description' => 'required|string'
]);
...
}
我一辈子都无法让它用JSON进行响应。文档指出,如果失败,它会抛出一个Illuminate'Contracts'Validation'ValidationException
异常,但我抓不到它
每当失败时,它总是重定向回编辑页面。显然我不想要这个,我想要json响应。
我刚刚尝试过用整个$v = Validator::make($request->all(), ...);
"手动写出",它确实有效,但如果$this->validate()
不起作用,那么使用它有什么意义?
$this->validate()
方法就是不适用于AJAX吗?我每次都要写很长的路吗?我做错什么了吗?!
以下是我尝试过的:
public function update(App'Permission $permission, UpdatePermissionRequest $request)
{
/** Redirects rather than returns JSON if the validation fails **/
}
----------------------------------
public function update(App'Permission $permission, Request $request)
{
$this->validate($request, [
'permission_description' => 'required|string'
]);
/** AND I've also tried: **/
try {
$this->validate($request, ['permission_description' => 'required|string']);
} catch ('Illuminate'Contracts'Validation'ValidationException $e {
echo $e; /** Echoing for debug reasons **/
exit;
}
...
/** Still redirects the browser, even if it is an AJAX request **/
}
-----------------------------------------
use Validator;
...
public function update(App'Permission $permission, Request $request)
{
$v = Validator::make($request->all(), [
'permission_description' => 'required|string'
]);
if($v->fails())
{
return response()->json(['reply' => false]);
}
/** Works **/
}
更新文档不正确。它声明$this->validate()
方法抛出一个Illuminate'Contracts'Validation'ValidationException
,但它没有。它抛出一个Illuminate'Http'Exception'HttpResponseException
异常。
简单地告诉您希望在头中使用json也应该解决这个问题。Laravel检查请求是ajax还是json。
if ($this->ajax() || $this->wantsJson())
{
return new JsonResponse($errors, 422);
}
解决方案:
添加标题
接受:application/json
文档说最好在控制器中验证AJAX请求的说法根本不正确。
如果你从你链接的内容向下滚动一点,你会在FormValidation部分下看到这一点
如果验证失败,将生成重定向响应以发送用户返回到他们以前的位置。错误也将闪烁以便它们可用于显示。如果请求AJAX请求,带有422状态代码的HTTP响应返回给用户,包括验证的JSON表示错误。
换句话说,没有理由不能在一个简单的FormRequest和简单的代码中做到这一点。它将自动处理它是AJAX调用的事实,并返回适当的HTTP响应。
我一直在我的L5应用程序中这样做——它完美地工作。
好的,所以看起来有两个促成因素。
-
它重定向而不是用JSON响应的原因是AJAX请求上没有设置X-Requested-Wise字段。这个应用程序的AJAX包装是为了处理跨域请求而设置的,这似乎去掉了X-Requested-Wise字段,这使得最终请求对服务器来说看起来不是AJAX,因此重定向。
-
它没有捕获
Illuminate'Contracts'Validation'ValidationException
异常的原因是该异常没有被抛出。如果打开Illuminate'Foundation'Validation'ValidatesRequest.php
并搜索函数throwValidationException()
,它实际上会抛出一个HttpResponseException
。我试图捕获HttpResponseException
,但它被成功捕获了——我认为文档是错误的。
根据本文的回答,解决方案是删除ajax请求上的跨域属性,或者手动添加X-Requested-WithHeader。这将使应用程序看到这是一个AJAX请求。
如果您想手动捕获异常,您需要捕获HttpResponseException
,而不是ValidationException
。