通过 JavaScript 和 Laravel 验证表单请求


上一篇教程中,我们结合 Vuex 和 Laravel 实现了表单提交功能,目前看来,工作的很好,但是有个遗憾,就是没有对表单提交数据做任何校验,所以我们将在这篇教程中来弥补这个缺憾,并且在前端和后端都加上校验。

第一步:在 NewCafe.vue 组件中添加前端校验

首先我们在前端给表单提交添加校验功能,打开 NewCafe.vue,在数据模型中新增一个 validations 对象为每个字段设置验证占位符:

其中 is_valid 字段标识是否验证成功,而 text 字段标识验证文本。

第二步:添加验证失败通知

接下来,需要实现某个字段验证失败给用户发送通知。我们为每个输入字段定义一个 <span> 元素来展示验证失败消息,例如,针对 name 字段对应的 <span> 元素如下:

其他字段依次类推,这样,我们就可以标记出验证失败的输入字段并自定义验证失败消息:

此外,还定义了一个样式文件 resources/assets/sass/components/_validations.scss,并在 resources/assets/sass/app.scss 中引入,对应文件请在 https://github.com/nonfu/roastapp 源码中查看。

第三步:构建 JavaScript 验证函数

我们将在这一步定义真正的前端验证实现,对应的字段验证规则描述如下:

  • name:必填字符串
  • address:必填字符串
  • city:必填字符串
  • state:必填字符串
  • zip:必填字符串并且必须是格式正确的邮政编码

接下来在 NewCafe 组件的 methods 中新增一个表单验证函数 validateNewCafe,在该函数中初始化一个判定表单是否验证成功的变量,默认设置为 true,并将其返回:

然后在 submitNewCafe 方法中调用这个方法,如果表单验证通过,才会提交表单:

最后我们来实现 validateNewCafe 方法:

我们会对输入字段按照相应的验证规则进行验证,如果验证失败,则设置对应字段的 is_valid 值为 false,同时将表单验证变量 validNewCafeForm 设置为 false,并验证失败消息字段 text 以便在之前定义的 <span> 元素中显示。

至此,我们的前端表单验证功能就完成了,运行 npm run dev 重新构建项目,就可以在 http://roast.test/#/cafes/new 页面中测试了:

完成了前端表单验证还不够,接下来还要在 Laravel API 端对请求数据进行验证,以避免非法用户通过 API 方式调用接口,绕开浏览器 JavaScript 验证逻辑。

第四步:为新增咖啡店构建 Laravel 请求验证类

现在让我们开始编写服务端验证代码吧,在 Laravel 后端编写代码比较轻松,因为 Laravel 已经自带了验证器功能,我们只需要组织代码调用相应的 API 就可以了,我们将通过表单请求验证来实现我们新增咖啡店的请求验证。

首先需要创建请求验证类:

该命令会在 /app/Http/Requests 目录下创建一个 StoreCafeRequest 请求验证类,我们将通过这个验证类验证新增咖啡店请求。

打开这个 StoreCafeRequest.php 文件,这个请求验证类默认包含两个方法:一个是 authorize() 方法,用于判断请求者是否有权限访问这个请求,由于我们已经在路由定义的时候定义过通过相应中间件 auth:api 进行权限过滤,所以这里将返回值设置为 true 即可;另一个是 rules() 方法,用于设置各个请求字段的验证规则,我们主要关注这个方法(Laravel 支持的完整验证规则可参考官方文档),编写字段验证规则如下:

这样,我们就完成了服务器端验证规则编写,对应验证失败请求,Laravel 将会返回 400 响应( Ajax 请求返回状态码为 422),并返回验证失败信息,我们可以在客户端通过捕获响应状态码及失败消息进行处理即可。

当然这还不算完,我们还可以为验证失败请求自定义每个字段的失败消息,并且需要将这个请求验证类添加到控制器路由中才能生效。

第五步:自定义验证失败消息

对于验证失败字段,会有默认的失败消息,但往往因为可读性问题并不能满足我们的需要,我们可以在请求验证类中对验证字段失败消息进行自定义,只需在这个类中重写 messages() 方法即可,该方法和 rules 方法类似,也返回键值对数组,对应的消息自定义格式如下:

我们可以为每个字段的每个验证规则自定义验证失败消息,也可以自定义一个验证失败消息子集。以 StoreCafeRequest 为例,我们可以定义 messages() 方法如下:

至此,我们已经完成新增咖啡店请求验证类的编写,StoreCafeRequest.php 的完整代码如下:

接下来,还需要将其添加到控制器路由中,以便实现请求验证。

第六步:添加请求验证类到控制器路由

打开 App\Http\Controllers\API\CafesController.php,将 StoreCafeRequest 注入到 postNewCafe() 方法:

注:如果你使用的不是 PHPStorm 这种集成 IDE,还需要在控制器顶部引入这个类:use App\Http\Requests\StoreCafeRequest;

这样,在这个方法运行之前会自动自行请求验证类 StoreCafeRequest,如果验证失败会直接返回,验证成功才会继续方法内代码执行。

至此,我们已经完成了新增咖啡店请求前后端验证,我们测试一个咖啡店名小于两个字符的表单提交,前端验证成功,但后端验证失败,返回状态码为 422,错误消息在 errors 中可以解析出来:


<< 上一篇: 通过 Vue 组件、Vue Router、Vuex 和 Laravel 实现表单提交

>> 下一篇: 通过高德地图 Web 服务 API 对咖啡店地址进行地理编码