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

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

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 15

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

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

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

加锁

5年前 评论

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

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

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

redis 🔒

5年前 评论
白小二

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

5年前 评论
giao哥

redis setnx 看下

5年前 评论

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

5年前 评论

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

5年前 评论

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

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

5年前 评论

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

5年前 评论

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

5年前 评论

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

5年前 评论
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);

    }
5年前 评论

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