简单的六种防止数据重复提交的方法!(六招轻松防止数据重复提交!)

原创
ithorizon 7个月前 (10-20) 阅读数 11 #后端开发

六招轻松防止数据重复提交!

一、前端防止重复提交

前端防止数据重复提交核心是通过控制按钮的可用状态,以下是一些常见的方法:

1. 按钮禁用

在提交按钮上添加disabled属性,当点击后立即禁用该按钮,防止二次点击。

<button id="submitBtn" type="submit" disabled>提交</button>

<script>

document.getElementById('submitBtn').addEventListener('click', function() {

this.disabled = true; // 禁用按钮

// 执行提交操作

});

</script>

2. 防止表单重复提交

通过在表单元素上添加一个隐藏的input字段,记录是否已提交,然后在提交前检查该字段。

<form id="myForm">

<input type="hidden" id="isSubmitted" value="0">

<button type="submit">提交</button>

</form>

<script>

document.getElementById('myForm').addEventListener('submit', function() {

if (document.getElementById('isSubmitted').value === '1') {

return false; // 如果已提交,则阻止表单提交

}

document.getElementById('isSubmitted').value = '1'; // 标记为已提交

// 执行提交操作

});

</script>

二、后端防止重复提交

后端防止数据重复提交核心是通过验证请求的唯一性,以下是一些常见的方法:

1. 唯一标识符

为每个请求生成一个唯一标识符,通常使用UUID,然后在提交时将该标识符发送给后端,后端验证该标识符是否已存在。

// 生成UUID的JavaScript代码

function generateUUID() {

var d = new Date().getTime(); // 获取当前时间

if (typeof performance !== 'undefined' && typeof performance.now === 'function'){

d += performance.now(); // 使用高精度时间

}

return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {

var r = (d + Math.random()*16)%16 | 0;

d = Math.floor(d/16);

return (c === 'x' ? r : (r&0x3|0x8)).toString(16);

});

}

// 使用UUID防止重复提交

<button id="submitBtn" type="submit">提交</button>

<script>

var uuid = generateUUID();

document.getElementById('submitBtn').addEventListener('click', function() {

// 在请求中携带UUID

// 执行提交操作,将uuid作为参数发送给后端

});

</script>

2. 令牌机制

为每个用户会话生成一个令牌,提交时将该令牌发送给后端,后端验证令牌是否有效,有效则处理请求,然后立即失效该令牌。

// 假设后端生成了令牌并存储在session中

// 前端获取令牌并发送到后端

<input type="hidden" id="token" value="your-token">

<form id="myForm">

<input type="hidden" name="token" value="<%= session.token %>">

<button type="submit">提交</button>

</form>

// 后端验证令牌

app.post('/submit', function(req, res) {

var token = req.body.token;

if (token === session.token) {

// 处理请求

session.token = null; // 失效令牌

} else {

// 返回谬误信息

}

});

三、数据库防止重复提交

在数据库层面,可以通过以下行为防止数据重复提交:

1. 唯一索引

为也许重复的字段添加唯一索引,如果插入时出现冲突,则捕获异常并处理。

CREATE TABLE your_table (

id INT AUTO_INCREMENT PRIMARY KEY,

unique_field VARCHAR(255) UNIQUE

);

// 插入数据时捕获异常

try {

// 执行插入操作

} catch (Exception $e) {

// 如果捕获到唯一索引冲突的异常,则处理

}

2. 开朗锁

通过在数据表中添加一个版本号字段,每次更新数据时检查版本号是否一致,如果一致则更新数据并增长版本号,否则拒绝更新。

CREATE TABLE your_table (

id INT AUTO_INCREMENT PRIMARY KEY,

version INT,

data VARCHAR(255)

);

// 更新数据时检查版本号

try {

$currentVersion = $database->query("SELECT version FROM your_table WHERE id = $id")->fetchColumn();

$newVersion = $currentVersion + 1;

$database->exec("UPDATE your_table SET data = '$data', version = $newVersion WHERE id = $id AND version = $currentVersion");

} catch (Exception $e) {

// 如果版本号不一致,则处理

}

四、分布式系统防止重复提交

在分布式系统中,可以使用以下方法防止数据重复提交:

1. 分布式锁

使用分布式锁来保证同一时间只有一个请求能执行特定的操作。

// 假设使用Redis实现分布式锁

function acquireLock($key, $value) {

return Redis::set($key, $value, ['nx', 'ex' => 60]);

}

function releaseLock($key, $value) {

$script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";

return Redis::eval($script, 1, $key, $value);

}

// 使用分布式锁

try {

if (acquireLock('lock_key', 'unique_value')) {

// 执行操作

releaseLock('lock_key', 'unique_value');

} else {

// 处理锁获取未果的情况

}

} catch (Exception $e) {

// 处理异常

}

2. 消息队列

使用消息队列确保请求按顺序处理,从而避免重复提交。

// 假设使用RabbitMQ作为消息队列

// 生产者发送消息

channel.basic_publish('exchange', 'queue_key', '', json_encode($data));

// 消费者接收消息并处理

channel.basic_consume('callback_function', '', false, false, false, false, function($msg) {

$data = json_decode($msg->body, true);

// 处理数据

$msg->ack();

});

五、其他防止重复提交的方法

除了上述方法,还有一些其他的技巧可以帮助防止数据重复提交:

1. 时间戳

使用时间戳作为请求的一部分,后端验证时间戳是否在合理范围内。

// 前端发送时间戳

var timestamp = Date.now();

// 后端验证时间戳

if (Math.abs(Date.now() - timestamp) < 10000) {

// 时间戳在10秒内,处理请求

} else {

// 时间戳超时,拒绝请求

}

2. 双重检查锁

在代码中实现双重检查锁,以确保在多线程环境下不会重复执行相同的操作。

// Java中的双重检查锁

public synchronized void method() {

if (someCondition) {

synchronized (this) {

if (someCondition) {

// 执行操作

}

}

}

}

六、总结

防止数据重复提交是保证系统稳定性和数据一致性的重要措施。本文介绍了六种常见的方法,包括前端控制、后端验证、数据库约束、分布式系统锁、消息队列以及其他技巧。在实际应用中,可以采取系统的具体情况选择合适的方法或组合使用多种方法,以大致有最佳的保护效果。


本文由IT视界版权所有,禁止未经同意的情况下转发

文章标签: 后端开发


热门