V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Trinity888
V2EX  ›  程序员

表单提交,测试时发现重复点击后,造成后台数据重复问题,到底是前端的工作,还是开发人员的工作?

  •  1
     
  •   Trinity888 · 2020-10-28 11:09:44 +08:00 · 9079 次点击
    这是一个创建于 396 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前端开发人员:只负责静态界面、表单校验及相应界面跳转、交互效果的实现

    后台开发人员:负责业务逻辑及数据动态内容开发

    现测试人员发现:表单提交时,重复点击多次提交按钮,造成数据重复问题。

    现在分析:

    1 ) 表单提交按钮控制,谁来做?

    是前端没有把界面验证做好(例如按钮只能点击一次),还是后台开发没有控制?
    

    2 ) 什么阶段来验证?

    前端开发完成后,没有验证测试通过,还是后台开发人员全部完成后验证?
    
    115 条回复    2020-10-29 17:54:08 +08:00
    1  2  
    becauseIdo
        1
    becauseIdo   2020-10-28 11:14:36 +08:00   ❤️ 18
    前后端都得做。
    hryen
        2
    hryen   2020-10-28 11:14:45 +08:00   ❤️ 5
    后端不能相信前端,前端也应该做控制,所以应该是都有责任 /狗头
    redtea
        3
    redtea   2020-10-28 11:15:34 +08:00 via iPhone
    后端必须做,前端建议做。前后端连调通过再让测试验证。
    eason1874
        4
    eason1874   2020-10-28 11:16:34 +08:00   ❤️ 11
    都有责任。前端提交时按钮要 disabled,提交成功后要清空表单,提示成功,阻止重复提交。

    后端要验证,防止出错重试或者恶意导致的重复提交,比如二次提交加验证码,比如限制两次提交的时间间隔。
    saulshao
        5
    saulshao   2020-10-28 11:16:44 +08:00   ❤️ 1
    后端必须做这种检查,因为你无法确定重复数据是由前端提交的,还是由攻击者提交的。
    leopod1995
        6
    leopod1995   2020-10-28 11:16:52 +08:00
    硬要分锅 我觉得是后端占 80%

    就算前端只能点击一次 api 直接一秒 call >100 次呢
    jinhan13789991
        7
    jinhan13789991   2020-10-28 11:17:19 +08:00
    都要做,当然如果是赶工出来的,那就是正常。
    如果是开发时间充足,两边都要做。
    mirrorpen
        8
    mirrorpen   2020-10-28 11:18:03 +08:00
    前端提交表单后,提交按钮变为不可点击
    后端做 CSRF
    mosliu
        9
    mosliu   2020-10-28 11:18:48 +08:00
    前后端都要做相应处理。
    只要没有事先约定。
    后端要默认前端是啥也没做的
    前端要默认后端是啥都不想的
    HashV2
        10
    HashV2   2020-10-28 11:19:05 +08:00
    我个人觉得后端再不相信前端也不做这种防错吧

    重复表单如果有业务逻辑可以判断重复那后端肯定要加验证

    如果没有的话,就是前端的问题啊, 点击提交按钮禁用显示加载动画 等后端处理完 再显示结果+按钮可用就好了.
    wysnylc
        11
    wysnylc   2020-10-28 11:20:42 +08:00   ❤️ 9
    后端的问题,表单重复提交这问题起码十年以上了你就不能百度学学怎么解决?
    young1lin
        12
    young1lin   2020-10-28 11:42:42 +08:00
    都得做,后端一定做得要更细致点。前端做可以限流
    ryuka
        13
    ryuka   2020-10-28 12:01:52 +08:00   ❤️ 1
    幂等性设计啊
    tesguest123
        14
    tesguest123   2020-10-28 12:06:21 +08:00 via Android
    后端需要随机 token
    tesguest123
        15
    tesguest123   2020-10-28 12:08:08 +08:00 via Android
    @tesguest123 前端需要。跳转。刷新。清空表单等
    icyalala
        16
    icyalala   2020-10-28 12:12:06 +08:00
    从功能上来讲当然是前端的锅,就算后端验证,用户也会看到错误提示。
    laravel
        17
    laravel   2020-10-28 12:35:22 +08:00
    我以前做前端的时候,前端数据显示有问题,老大以为前端代码有问题,后来我一查,api 返回数据的问题。

    对于重复提交的问题。
    1 、前端点击按钮提交后,loading 改成 true, 按钮改成 loading 状态,此时点击按钮因为判断 loading 为 true 就不执行任何操作了。
    2 、后端每个 api 请求可以加个 unique request id,靠这个判断是不是重复请求。
    acmore
        18
    acmore   2020-10-28 12:35:46 +08:00   ❤️ 3
    幂等和防抖都要做的。
    rekulas
        19
    rekulas   2020-10-28 12:42:47 +08:00   ❤️ 1
    前后都做是最好的 但是会增加不少工作量

    非要甩锅就甩前端,毕竟对后端来说这只能算是流程优化,对前端来说已经算 bug 了(因重复提交导致的数据异常除外)。。。

    目前来看,互联网所见的大部分服务都是前端做限制,毕竟前端限制简单粗暴快,只要前端做好后端基本不会受到重复数据了,只有 hacker 会破解前端来重复提交,不过对 hacker 来说做这种简单后端限制意义也不大

    有些框架倒是自带了后端验证,但是个人不是很喜欢
    treblex
        20
    treblex   2020-10-28 12:43:55 +08:00
    @mirrorpen #8 请问一下,传统的后端使用模版渲染 html 可以把 csrf 嵌入到页面中,这是安全的, 前后端分离的时候应该怎么处理呢,使用 api 获取 key 吗,似乎并不安全
    xrr2016
        21
    xrr2016   2020-10-28 12:45:22 +08:00
    前端 20%,后端 80%
    vision1900
        22
    vision1900   2020-10-28 12:48:32 +08:00
    不是很清楚其他 UI 库,Ant Deisgn 按钮的 loading 属性为 true 的时候会自动拒绝响应 click 事件,前端开发者只需关心 loading 的状态即可
    opengps
        23
    opengps   2020-10-28 12:49:10 +08:00 via Android
    主要在于后端
    eGlhb2Jhb2Jhbw
        24
    eGlhb2Jhb2Jhbw   2020-10-28 12:51:37 +08:00
    前端改了就能完全保证不产生重复数据了吗?不能。后端修改完了呢?前端会是什么效果,重复点击的时候产生无用请求乃至抛错,所以也得改。
    cmdOptionKana
        25
    cmdOptionKana   2020-10-28 13:09:47 +08:00   ❤️ 7
    前端的主要负责对象是用户,最主要的责任给用户合理的暗示:

    - 比如通过按钮失效来告诉用户点击成功了(不然用户会烦躁 “究竟点到了没”)
    - 比如通过进度条(或转圈圈)来告诉用户正在处理中。

    后端的主要负责对象是公司(公司数据的安全、服务器的稳定),最主要的责任是假设每一个请求都有可能是攻击。
    justsosososo
        26
    justsosososo   2020-10-28 13:14:00 +08:00
    你写前端节流不会么 这类情况我们都是前端做
    phpcxy
        27
    phpcxy   2020-10-28 13:15:25 +08:00
    主锅在后端。
    cmdOptionKana
        28
    cmdOptionKana   2020-10-28 13:18:09 +08:00   ❤️ 2
    因此,数据重复问题 100% 是后端的责任。

    另外,用户点击按钮的 “使用体验”(能感觉到点击生效吗、能感觉到正在处理吗)则是前端的责任。

    如果用户体验不好,烦躁地多次连击按钮,这个烦躁应该由前端负责解决,但后台数据是否重复这个前端是解决不了的(因为还有攻击者不走正常前端页面)。
    cmdOptionKana
        29
    cmdOptionKana   2020-10-28 13:21:21 +08:00
    注意,前端使按钮失效,说来说去都是为了让用户体验更好而已,**绝对不是** 为了让后端不接受重复提交的,因为这对于前端来说是一个不可能的任务,既然不可能,就没有责任。
    mirrorpen
        30
    mirrorpen   2020-10-28 13:46:04 +08:00   ❤️ 1
    @suke971219 前端向后端请求个 token,后端 token 放 redis 啥的,请求表单时做校验
    samuel
        31
    samuel   2020-10-28 13:54:06 +08:00
    如果在产品设计时就没有定义好,重复点击或重复提交表单该怎么处理,造成前后端撕逼,那就是产品经理的责任了
    clf
        32
    clf   2020-10-28 13:54:18 +08:00   ❤️ 1
    前后端都得做。

    前端控制点击状态是为了避免双击或者网络不佳时有人多次点击。另外,每次进入这个页面的时候,前端最好生成一个 key,表单提交的时候带上 key,用于后端判断是否多次点击。(当前端判断请求失败 /允许再次请求的时候,前端才会刷新这个 key )
    同样的,对于响应速度一般的接口(尤其是插入,容易造成业务数据重复)后端要采用 用户-key-接口 为单元的锁。
    woostundy
        33
    woostundy   2020-10-28 13:57:27 +08:00
    前端做吧。
    l890908
        34
    l890908   2020-10-28 13:59:08 +08:00
    有没有人能说说前后端都分别怎么做最好?
    simonlu9
        35
    simonlu9   2020-10-28 14:02:29 +08:00
    上分布式锁
    Elissa
        36
    Elissa   2020-10-28 14:07:41 +08:00 via Android
    最极端的情况,前端只对提交成功做了回调,那么后端就需要把提交重复、提交写入失败、网络问题等等情况都要返回提交识别的状态码,这样就算前端不验证,数据也是安全的
    otakustay
        37
    otakustay   2020-10-28 14:20:10 +08:00   ❤️ 5
    @rekulas 不不,非要甩锅就甩后端,对前端来说只是用户体验不好,对后端来说这可是 CSRF 漏洞
    otakustay
        38
    otakustay   2020-10-28 14:21:30 +08:00
    不过我觉得最大的锅在产品和交互设计
    fengmumu
        39
    fengmumu   2020-10-28 14:25:27 +08:00
    @eason1874 不一定要清空,但是提交时禁止,并且有提交提示要的
    sevenzhou1218
        40
    sevenzhou1218   2020-10-28 14:28:46 +08:00   ❤️ 1
    说前端大部分责任的真是够了...
    fengmumu
        41
    fengmumu   2020-10-28 14:30:41 +08:00
    说到校验顺序,不是开发完成,联调,功能实现了,给产品看,产品确定完成度,然后交由测试做测试,看是否有隐藏的 bug 和不兼容的情况
    另外 非要说问题,产品规划里这个说明咩有,前端自测,后端联调,都跑不了,毕竟所有相关的都没有考虑这个问题,然后交互是否设计了提交时的样式。。。
    glacial
        42
    glacial   2020-10-28 14:31:41 +08:00   ❤️ 1
    作为一个老司机 我可以明确的告拆你 这种事 就是谁能拍板 就听谁的 你们后端大佬说了算 那完全可以 让前端改,从技术实现上来说 前端好改 只要提交后加个 disable 就可以了, 当然有人说了 不行 你们后端也得加 对此 我做过多年的项目经验来讲认为 可以有 但没必要, 你看看 支付宝 微信 的接口会给你加这个吗,你重复调不也会产生重复数据。你让他们给你改试试
    Sapp
        43
    Sapp   2020-10-28 14:32:59 +08:00   ❤️ 1
    前端最好做,后端一定要做
    前端做了也改变不了其他人调用你的接口出现这个问题,除非你打算让所有的前端包括客户端都做
    后端做了一定能解决这个问题,哪怕前端一点都不做
    fatpower
        44
    fatpower   2020-10-28 14:43:10 +08:00
    前端后端都要做
    elfive
        45
    elfive   2020-10-28 14:44:42 +08:00 via iPhone
    避免重复提交,请使用幂等
    exmario
        46
    exmario   2020-10-28 14:57:40 +08:00
    肯定是后端的锅,前端只管提示,后端管处理
    DOLLOR
        47
    DOLLOR   2020-10-28 14:59:28 +08:00
    重复提交问题是后端的锅。
    前端只负责提醒用户状态,不负责处理重复提交问题。
    Thresh
        48
    Thresh   2020-10-28 15:02:42 +08:00
    前端要做:尽量减少到后端的可能,一来是有效减低幂等问题的可能,二来在高 qps 场景下避免重复点击可以给服务端适当减负
    后端要做:这 tm 本来就是你自己幂等的问题。你 tm 还不做?
    zaul
        49
    zaul   2020-10-28 15:09:59 +08:00
    用户的锅,谁 TM 这么脑瘫连续点提交干什么?
    axex
        50
    axex   2020-10-28 15:37:53 +08:00
    后端的锅比较大
    wangritian
        51
    wangritian   2020-10-28 15:39:08 +08:00
    前端方案:按钮点击后禁用,response 回来了解禁
    后端方案:csrf_token 需要放在 session 而非 cookie,并且用分布式锁确保 session 的读取和更新两步操作具有原子性
    攻击方案:先抓取页面,获得 csrf_token,然后 post,无限循环
    结论:前端解决重复提交的成本低,后端的 csrf_token 继续放 cookie,在防火墙级别封掉过大流量的 IP,然后禁用攻击者账户,清理垃圾数据
    a719031256
        52
    a719031256   2020-10-28 15:40:49 +08:00   ❤️ 1
    后端的锅,居然没做数据重复判断,php ?
    zhuweiyou
        53
    zhuweiyou   2020-10-28 15:44:18 +08:00
    后端必须做,

    前端是交互问题, 比如 disable 什么的
    哪怕前端不做, 后端也应该返回错误提示
    wangxiaoaer
        54
    wangxiaoaer   2020-10-28 15:52:03 +08:00 via iPhone
    @otakustay 额,csrf 表示不背这个锅。
    HiCode
        56
    HiCode   2020-10-28 16:10:17 +08:00
    @leopod1995

    你的 80%是怎么算的?

    前端做是考虑用户体验,后端做是考虑数据安全。前后端各自基于不同的角度去考量,还能分出个后端 80%,前端 20%的占比来?

    笑话!
    1107139144
        57
    1107139144   2020-10-28 16:10:45 +08:00
    后端做幂等,前端按钮控制
    winecat
        58
    winecat   2020-10-28 16:15:04 +08:00
    几乎是后端的锅,不用想,再怎么耍赖,也还是后端的锅.
    前端也可以做验证,但也只是做得更好的体验而已,最终验证只能是后端呀.
    JJstyle
        59
    JJstyle   2020-10-28 16:16:58 +08:00
    前后端分离的项目,csrf token 应该不管用了, 因为前端前端生成表单时,是不需要请求后端 API 的
    lookbackagain
        60
    lookbackagain   2020-10-28 16:19:16 +08:00
    这个要看功能,有些功能是不需要防止重复提交的,但是有需要避免重复提交的,不管前端做没做,后端的锅,前端只是体验问题
    xuanbg
        61
    xuanbg   2020-10-28 16:39:45 +08:00
    前后端都要做防重复提交!前端主要是点击后禁用按钮,等接口返回结果后再解除禁用状态。后端一言以蔽之:接口幂等。
    JustinJie
        62
    JustinJie   2020-10-28 16:44:15 +08:00
    前段防抖, 后端幂等
    rekulas
        63
    rekulas   2020-10-28 16:44:35 +08:00
    @otakustay 重放请求跟 csrf 似乎没有关系,csrf 是数据验证导致的问题而不是重放
    shawndev
        64
    shawndev   2020-10-28 17:00:19 +08:00
    后端必须做,前端建议做
    pigzzz
        65
    pigzzz   2020-10-28 17:11:19 +08:00
    前端做是为了体验
    后端做是为了安全
    yeahvov
        66
    yeahvov   2020-10-28 17:15:02 +08:00
    后端必须做 前端不闲的话也可以做
    romisanic
        67
    romisanic   2020-10-28 17:20:19 +08:00
    前后端都要做,必备的基础。
    产品设计的时候,也应该考虑到点击后按钮的状态和防抖等,如果没有,那产品也有锅。
    yiqunz
        68
    yiqunz   2020-10-28 17:21:57 +08:00
    都得做,别说什么前端只是建议,
    假如是内网或者没人攻击的系统,前端做了就直接能避免重复问题了,可以降低服务端压力(有的用户就是骚,一秒不返回我就疯狂点按钮)
    当然考虑安全性后端是要做的,实际情况是很多内网项目宁愿前端加个按钮失效也懒得后端做。
    就跟必填字段类似 前端不做 每个字段都来请求后端返回错误,也是挺搞笑的,至少我没见过这样的产品。
    gengzi
        69
    gengzi   2020-10-28 17:24:13 +08:00
    幂等
    otakustay
        70
    otakustay   2020-10-28 18:05:34 +08:00
    @wangxiaoaer 请求重放是很典型的 CSRF 攻击之一啊
    otakustay
        71
    otakustay   2020-10-28 18:07:24 +08:00
    @rekulas 我的理解是,CSRF Token 不一定能解决重放的问题,但重放是 CSRF (客户端请求伪造)的一种。只是这种伪造不是基于攻击需求的带逻辑的伪造,是纯粹地拿已经发送过的请求作为伪造结果来用
    rekulas
        72
    rekulas   2020-10-28 20:05:10 +08:00
    @otakustay csrf 是 Cross site request forgery,严格来说我觉得单纯的重放不算 csrf,不过 csrf 是可以避免重放攻击(这是当然的 这其实是废话)
    whisky221
        73
    whisky221   2020-10-28 21:50:21 +08:00
    “到底是前端的工作,还是开发人员的工作?”

    前端再次被害,果然后端的眼里前端就不是开发,还好我正在转后端 ing
    wc951
        74
    wc951   2020-10-28 22:02:24 +08:00 via Android
    两边都要做,前端是为了用户体验,后端是为了数据安全
    tpsxiong
        75
    tpsxiong   2020-10-28 22:55:10 +08:00
    @rekulas 后端不做,如果 2 个人同时想取一个相同的昵称怎么办,而昵称又不能重复
    Felldeadbird
        76
    Felldeadbird   2020-10-28 23:22:59 +08:00
    主要责任在后端。
    weixiangzhe
        77
    weixiangzhe   2020-10-29 00:13:46 +08:00 via Android
    前端 debounce 加 loading 和 disable 可以处理
    kaiki
        78
    kaiki   2020-10-29 00:43:29 +08:00
    我前端后端都写,但是我前端后端都会加验证。
    后端不要相信前端发来的任何信息。
    dawniii
        79
    dawniii   2020-10-29 01:08:43 +08:00 via iPhone   ❤️ 1
    看场景

    1.假如是今日签到的按钮,后端肯定要做禁止重复签到的检验。

    2.假如是后台发文章的接口,如果后端有标题不能重复的判断,自然也就没法重复提交。

    3.假如还是发文章或者评论,并没有什么业务上的字段非重复要求,后端就没必要特殊处理,就算处理也是防止灌水处理吧。

    以上所有场景前端肯定应该做按钮 disable 处理的,前两个场景是正常的错误提示,最后一个场景是防止非预期的“灌水”。
    Balthild
        80
    Balthild   2020-10-29 03:54:28 +08:00
    都做。后端做来保证数据一致性,前端做来改善用户体验。
    jorneyr
        81
    jorneyr   2020-10-29 08:52:43 +08:00
    责任是后端的,前端要做也是让交互更友好,如果直接走接口测试工具如 Postman 也会出现重复提交,这下和前端没关系了吧,所以责任一目了然。
    zsdroid
        82
    zsdroid   2020-10-29 09:17:18 +08:00
    我纸笔已经准备好了,谁能告诉我前端 20%,后端 80%怎么算的?
    howellz
        83
    howellz   2020-10-29 09:24:44 +08:00
    前端算开发事故,后端算业务事故。前端 20 大板,后端 80 大板。
    howellz
        84
    howellz   2020-10-29 09:26:08 +08:00
    @zsdroid 你怎么直到我要发贴[dog],哈哈,用微积分算的行不行?哈哈。
    howellz
        85
    howellz   2020-10-29 09:26:41 +08:00
    @zaul 兄弟,到我们部门来吧,我们需要你~~~~
    rekulas
        86
    rekulas   2020-10-29 09:49:49 +08:00
    @tpsxiong 当然只能一个人占用啊,不验证重放并不是指不验证数据啊,我看楼上很多理解会影响了数据安全的,估计是误解重放和数据验证了,重放验证是第一层,数据验证是第二层,略过重放只会影响体验不会影响数据准确性
    no1xsyzy
        87
    no1xsyzy   2020-10-29 09:51:50 +08:00
    看看 v2 重复发两个相同内容的回复会发生什么~
    sdushn
        88
    sdushn   2020-10-29 09:54:10 +08:00
    应该是互不相信原则吧,前端肯定要做重复点击保护,后端也需要做相关保护吧,如果只有前端做保护,有人爆接口也没招
    notejava
        89
    notejava   2020-10-29 10:03:11 +08:00
    数据重复,后端背锅,数据库应加唯一约束。
    751327
        90
    751327   2020-10-29 10:07:26 +08:00
    一般这个时候我都会默默的加上,前端加不加我管不了。跟前端说又是一顿撕逼
    PEAL
        91
    PEAL   2020-10-29 10:07:47 +08:00
    都得做,对前端来说这叫交互,对后端来说这叫限流
    pianjiao
        92
    pianjiao   2020-10-29 10:08:57 +08:00 via Android
    前端最基本的要做表单提交的防抖!常识问题。 当然后端也要加
    751327
        93
    751327   2020-10-29 10:09:23 +08:00
    后端是兜底的,后端苦啊
    phpxiaowangzi
        94
    phpxiaowangzi   2020-10-29 10:12:08 +08:00
    都有责任,前端后端都要有验证机制
    mauve
        95
    mauve   2020-10-29 10:25:13 +08:00
    这个标题看得我:前端不算开发人员吗?
    kuro1
        96
    kuro1   2020-10-29 10:59:35 +08:00   ❤️ 1
    v2 就能重复发
    lx520
        97
    lx520   2020-10-29 11:12:14 +08:00
    如果是公开的网站肯定是后台的锅,如果内部网站肯定是前台的锅....内部网站不存在恶意攻击,前台用请求频率就可以判断是不是重复请求.
    CRonaldo9399
        98
    CRonaldo9399   2020-10-29 11:21:52 +08:00
    顺便问下,如果业务允许数据重复,后端该做些什么事?
    lscexpress
        99
    lscexpress   2020-10-29 11:25:25 +08:00
    @wysnylc 草泥马有一天要过河,就上了船。然后发现船一直没动,岸上的小伙伴大喊:草泥马,摆渡一下会死啊!
    domybestFujian
        100
    domybestFujian   2020-10-29 11:36:37 +08:00
    都重复数据了,主锅肯定在后端,前端重复提交只能算体验问题。
    1  2  
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2262 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 09:28 · PVG 17:28 · LAX 01:28 · JFK 04:28
    ♥ Do have faith in what you're doing.