防止直接访问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>
基于业务方面的控制
1)基于DB中退款订单状态的验证
2)利用数据库唯一索引机制的验证
3)基于缓存的计数器验证:
由于数据库的操作比较消耗性能,了解到redis的计数器也是原子性操作。果断采用计数器。既可以提高性能,还不用存储,而且能提升qps的峰值。还是以订单退款为例子:
每次request进来则新建一个以orderId为key的计数器,然后+1。如果>1(不能获得锁): 说明有操作在进行,删除。如果=1(获得锁): 可以操作。操作结束(删除锁):删除这个计数器。
前端防止重复提交,禁用按钮或链接
- <!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="#" οnclick="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" οnclick="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(){
- });