欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

防直接访问 防重复提交

程序员文章站 2022-06-12 12:42:01
...
防止直接访问PHP页面
1.可以在A加COOKIE,B判断COOKIE后用完删掉COOKIE
2. 使用$_SERVER['HTTP_REFERER'] 得到链接到当前页面的前一页面的地址
3.token令牌
<?php
/*
* PHP简单利用token防止表单重复提交
* 此处理方法纯粹是为了给初学者参考
*/
session_start();
function set_token()
{
    $_SESSION['token'] = md5(microtime(true));
}
function valid_token()
{
    $return = $_REQUEST['token'] === $_SESSION['token'] ? true : false;
    set_token();
    return $return;
}
//如果token为空则生成一个token
if (!isset($_SESSION['token']) || $_SESSION['token'] == '') {
    set_token();
}
if (isset($_POST['test'])) {
    if (!valid_token()) {
        echo "token error";
    } else {
        echo '成功提交,Value:' . $_POST['test'];
    }
}
?>
<form method="post" action="">
    <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>">
    <input type="text" name="test" value="Default">
    <input type="submit" value="提交"/>
</form>

ajax token防止重复提交

$.ajax({
    type: "POST",
    url: do_order_url,
    data: {
        '_csrf_token':_csrf_token, //token
        'item_id':item_id,
    },

基于业务方面的控制

1)基于DB中退款订单状态的验证

2)利用数据库唯一索引机制的验证

3)基于缓存的计数器验证:

由于数据库的操作比较消耗性能,了解到redis的计数器也是原子性操作。果断采用计数器。既可以提高性能,还不用存储,而且能提升qps的峰值。还是以订单退款为例子:
每次request进来则新建一个以orderId为key的计数器,然后+1。如果>1(不能获得锁): 说明有操作在进行,删除。如果=1(获得锁): 可以操作。操作结束(删除锁):删除这个计数器。

前端防止重复提交,禁用按钮或链接

Java代码

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">  
<html>  
<head>  
<title>测试</title>  
</head>  
<script language="javascript">  
var t = null;  
var flag = true;  
function check(obj) {  
    if (flag) {  
        obj.disabled = flag;  
        flag = false;  
        t = setTimeout(function(){disable(obj)}, 5000); // 5秒间隔  
        window.open("http://www.baidu.com", "newWindow");  
    }  
}  
  
function disable(obj) {  
    obj.disabled = flag;  
    flag = true;  
    if (t != null)  
    clearTimeout(t);  
}  
</script>  
<body>  
<a href="#" onclick="check(this)">ceshi1</a>  
</body>  
</html>

9秒后按钮激活代码

<input class="button" type="submit" name="rulesubmit" value="同 意" style="height: 23px">  
<input class="button" type="button" name="return" value="不同意" style="height: 23px" onclick="javascript:history.go(-1);">  
</center>  
</form>  
  
<script type="text/javascript">  
var secs = 9;  
var wait = secs * 1000;  
document.bbrules.rulesubmit.value = "同 意(" + secs + ")";  
document.bbrules.rulesubmit.disabled = true;  
for(i = 1; i <= secs; i++) {  
        window.setTimeout("update(" + i + ")", i * 1000);  
}  
window.setTimeout("timer()", wait);  
function update(num, value) {  
        if(num == (wait/1000)) {  
                document.bbrules.rulesubmit.value = "同 意";  
        } else {  
                printnr = (wait / 1000) - num;  
                document.bbrules.rulesubmit.value = "同 意(" + printnr + ")";  
        }  
}  
function timer() {  
        document.bbrules.rulesubmit.disabled = false;  
        document.bbrules.rulesubmit.value = "同 意";  
}  
</script>

Jquery one当使用 one() 方法时,每个元素只能运行一次事件处理器函数

$("p").one("click",function(){    
});