表单令牌的作用:避免表单的重复提交。当然还有另外一个原因,使用表单令牌可以防止黑客绕过表单,伪造数据进行提交。
首先,在前端页面的表单中,添加:<input type="hidden" name="__token__" value="{$Request.token}" />
比如下面的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="__PUBLIC__/static/bootstrap-4.3.1-dist/css/bootstrap.css">
<script src="__PUBLIC__/static/jquery-1.11.3.min.js"></script>
<script src="__PUBLIC__/static/bootstrap-4.3.1-dist/js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<h2>添加学生</h2>
<form id="form1" action="{:url('do_add')}" method="post">
<input type="hidden" name="__token__" value="{$Request.token}" >
<div class="form-group">
<label for="no">学号:</label>
<input type="text" class="form-control" id="no" name="no" placeholder="输入学号">
</div>
<div class="form-group">
<label for="name">姓名:</label>
<input type="text" class="form-control" id="name" name="name" placeholder="输入姓名">
</div>
<div class="form-group">
<label>性别:</label>
<input type="radio" name="sex" value="男" checked>男
<input type="radio" name="sex" value="女">女
</div>
<div class="form-group">
<label for="age">年龄:</label>
<input type="text" class="form-control" id="age" name="age" placeholder="输入年龄">
</div>
<button type="submit" class="btn btn-primary btn-block">提交</button>
</form>
</div>
</body>
</html>
在上面的代码中,有一行代码就是:
<input type="hidden" name="__token__" value="{$Request.token}" >
在验证器中,必须添加这样的验证规则:
protected $rule = [ '__token__' => 'require|token', ];
protected $message = [ '__token__.require' => '非法提交', '__token__.token' => '请不要重复提交表单' ];
比如下面的验证器
<?php
namespace app\index\validate;
use think\Validate;
//学生验证器
class Student extends Validate
{
//验证规则
protected $rule = [
'no' => 'require|integer',
'name' => 'require',
'sex' => 'require',
'age' => 'integer',
'__token__' => 'require|token',
];
//错误信息
protected $message = [
'no.require' => '学号必须',
'no.integer' => '学号必须是数字',
'name' => '姓名必须',
'sex' => '性别必须',
'age' => '年龄必须是数字',
'__token__.require' => '非法提交',
'__token__.token' => '请不要重复提交表单'
];
}
最后在保存数据时,记得使用验证器
public function do_add()
{
$data = input('post.');
//实例化模型对象
$stu = new Student();
try{
$ret = $stu->allowField(true)->validate(true)->save($data); //保存数据,返回影响的行数
if(false === $ret){
$this->error($stu->getError());
}else{
$this->success('添加成功',url('index'),'',1);
}
}catch (Exception $ex){
$this->error('保存失败,' . $ex->getMessage());
}
}