有什么更好的办法可以防止用户重复点击提交

就是我现在写了个积分系统,但是由于网页的卡顿,没有及时反馈给用户信息,有的时候用户会点击提交很多次,导致多次计算积分,除了前端JS控制按钮或者a标签,还有什么更好的方法吗

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 15

emmm……这玩意大厂都叫它:接口幂等

实现接口幂等性的几种方案

2年前 评论
Adachi 2年前
白小二 2年前
aa24615

加锁

2年前 评论

emmm……这玩意大厂都叫它:接口幂等

实现接口幂等性的几种方案

2年前 评论
Adachi 2年前
白小二 2年前

redis 🔒

2年前 评论
白小二

加一个数据签名sign用于保存表单状态,sign 选择 mysql,或者 redis驱动。有的人也选择 session,但是无法确保高并发sign的唯一性
mysql随意用一列,设置 unique 索引,redis 用有序集合。只要能实现 唯一性即可,唯一性 确保高可用,从性能出发推荐 redis

2年前 评论
giao哥

redis setnx 看下

2年前 评论

没解决卡顿的话。良好的提示和健壮接口,或者先假定成功,马上显示,然后出错再显示。

2年前 评论

点击后前端把按钮改为禁用状态,等请求结束返回成功再恢复为原始状态

2年前 评论

一个比较容易理解的解决方案是往用户的数据表中添加字段如 flag ,字段初始化默认值为 0,后端接收到用户请求后则将 flag 置为 1。在后端即将处理用户请求时,先判断数据表中该用户的flag是否为 0,是的话则处理请求,否则直接退出。

当然这个方法过于简陋,具体如何优化就看楼主自己咯。

2年前 评论

使用文件缓存或者redis都是不错的选择

2年前 评论

加载页面的时候,隐藏域里写个token,然后顺便服务端保存一下。 等下一次提交的时候带着这个token和服务端保存的对比。第一次提交过来后对比完成就删掉服务端的,第二次来的时候肯定对比不正确了。

2年前 评论

1.唯一索引 2.下单校验未确认订单,用户id,积分,请求时间与表中记录的某条完全一致

2年前 评论
zhanghaidi

以下代码是我以前做活码时候的场景,因为构造方法中需要搜集用户ip信息。实例化时候并发很大。经常出现数据库增加很多条相同的数据。后来改造在userJoin使用redis的 setnx解决了这一问题。

 public function __construct()
    {
        global $_W;

        $activityId =  intval(\YunShop::request()->id);
        if(!$activityId){
            return $this->errorJson('参数错误', [
                'status' => 0
            ]);
        }
        $this->activityId = $activityId;

        //搜集新加入此页面的用户
        $this->userJoin($activityId, $_W);
    }


     //搜集参与扫码记录
    protected function userJoin($activity_id, $_W)
    {
        $params = array(
            'uniacid' => \YunShop::app()->uniacid,
            'code_id' => $activity_id,
            'ip' => $_W['clientip'],
        );

        $lockCacheKey = 'userJoin' . \YunShop::app()->uniacid . $activity_id . $_W['clientip'] . date('Y-m-d H:i:s');

        $lockCacheRs = Redis::setnx($lockCacheKey, 1);
        if ($lockCacheRs != 1) {
            return false;
        }
        Redis::expire($lockCacheKey, 5);

        $data = [
            'uniacid' => \YunShop::app()->uniacid,
            'code_id' => $activity_id,
            'ip' => $_W['clientip'],
            'container' => $_W['container'],
            'os' => $_W['os'],
            'openid' => $_W['openid'] ? $_W['openid'] : ''
        ];
        ActivityUser::firstOrCreate($params, $data);

    }
2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!