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

前端校验还是后端校验的问题

  •  
  •   LuffyPro · 24 天前 · 2926 次点击

    RT,场景大致如下:

    • 某次表单提交,某些表单项的值没发生变化,前端需要把没变化的旧数据通过接口提交给后端吗?如果提交,后端该字段又有内容约束条件,需要校验相关数据是否合规同时是否跟旧数据一样(比如手机号不能重复,但提交上来的手机号又是自己的号码),如果不提交,前端需要判断该表单项数据是否发生变化,有变化才提交。

    个人看法:

    • 如果交给前端去校验,最好是能实现或者有现成的组件/特性能统一判断那些没发生变化表单项不提交,要不然单独判断每个表单比较麻烦(前端 vue )
    • 如果交给后端去判断,提交同个手机号码上来,感觉没有保留用户最初的想法,即:用户是想改成一样的,还是没做任何改动。相当于把判断交给后端去做,但多一层判断是否等于自己的判断是无意义的,因为用户改不改前端是知道的。

    想知道大佬们处理这种场景的选择和原因,另外前端有相关组件(比如 vue )吗?谢谢大家回复。

    37 条回复    2024-05-24 15:14:23 +08:00
    facebook47
        1
    facebook47  
       24 天前 via Android   ❤️ 8
    都校验🙈
    IDAEngine
        2
    IDAEngine  
       24 天前
    必须都校验,要么就全部交给后端,肯定不能交给用户
    InDom
        3
    InDom  
       24 天前   ❤️ 1
    首先,无论如何,后端必须校验,这是出于安全考虑。

    至于前端,建议校验,这是出于用户体验考虑。

    至于前端完全依赖后端校验,不是不行,说好听了叫最大化兼容性。
    lneoi
        4
    lneoi  
       24 天前
    提交的时候拿到数据遍历对比一下,并不是太麻烦。
    接口也可以约定一样的数值就视为不变,手机号什么的再多判定一下是不是用户本身。
    但如果接口不做校验,万一直接调接口做数据修改呢
    Removable
        5
    Removable  
       24 天前
    不要相信用户端传入的任何数据,后端必须要有最后的关卡
    rabbbit
        6
    rabbbit  
       24 天前
    大多数情况前后都校验,非挑一个就后端校验。内部用的,xx 玩具管理系统啥的随意。
    rabbbit
        7
    rabbbit  
       24 天前
    例如修改绑定手机号的功能,接口设计应该是:
    1 校验用,接受手机号作为参数,如果手机号和绑定的手机号一致,返回布尔值。
    2 提交用,接受手机号作为参数,如果手机号和绑定手机号一致,返回错误码。

    然后前端在用户输入时调用接口 1 校验手机号是否和绑定的手机号一致,在用户点击提交时调用接口 2 提交手机号。
    当然很多情况下,例如内部用的 xx 管理系统,接口 1 就省了。
    rabbbit
        8
    rabbbit  
       24 天前
    校验用,接受手机号作为参数,如果手机号和绑定的手机号一致,返回布尔值。
    ->
    校验用,接受手机号作为参数,判断手机号是否和绑定的手机号一致,返回布尔值。
    LuffyPro
        9
    LuffyPro  
    OP
       24 天前
    @facebook47 @IDAEngine @InDom @lneoi @Removable @rabbbit 谢谢大家回复
    当然这里后端是要校验数据的,但我的意思不是后端不做校验,而是有没有必要特殊处理这种数据没变化但又把数据提交上来的场景,比如上面例子说的手机号码,手机号码是唯一的,如果你传过来的手机号码,数据库中已经存在了,后端就不给提交,但现在后端需要校验多一次传过来的手机号码是否等于他自己的手机号码,如果是这种特殊情况,能让他提交。如果前端校验该表单项没发生数据变化不提交上来,后端就不需要做这层校验了,接口传上来的手机号默认都是当作想要修改的。不过这样前端需要提交前判断相关表单项,而且不大可能每个表单项都去做这种数据无变化的判断,来决定要不要将手机号码传给接口。
    LuffyPro
        10
    LuffyPro  
    OP
       24 天前
    @LuffyPro 不传上来,后端当作你不想改手机号码,传上来表示你想改手机号码。
    rabbbit
        11
    rabbbit  
       24 天前
    @LuffyPro
    看你的业务场景需求,没具体场景无法判断。
    举个例子,如果你的表单里有多项,例如有个表单的作用是编辑餐厅的信息,有地址、手机号、营业时间等等,让前端去校验然后不发送未变更的表单项是不合理的。
    LuffyPro
        12
    LuffyPro  
    OP
       24 天前
    @rabbbit 嗯嗯,不过这个判断交给后端去判断感觉也怪怪的,相当于把这个数据是否变化的判断交给后端去做了。当然你列举里面的很多字段是不需要判断数据是否发生变化的,因为没有手机号码有特殊的唯一性要求,其他数据提交上来直接覆盖就行了。
    rabbbit
        13
    rabbbit  
       24 天前
    当然,后端非说防止其他人改了别的选项被覆盖也行。例如两个人同时编辑一个页面,后提交的那个会把先提交的那个覆盖掉。
    这时候就谁屌大厉害听谁的。
    rabbbit
        14
    rabbbit  
       24 天前
    @LuffyPro
    或许你们可以改页面的设计,把修改手机号放在单独的表单中,而不是和地址、营业时间混在一个表单里。
    old9
        15
    old9  
       24 天前
    前端只提交改动过的数据,前端框架一般都可以或通过库来判断是否改动过,关键词搜搜 form state dirty/pristine
    后端就正常处理,前端提交上来什么就校验什么
    IvanLi127
        16
    IvanLi127  
       23 天前   ❤️ 2
    前端校验只是为了提升用户体验,后端校验是为了数据合法性。
    不过你说手机号变化这事,正常来说用户没碰过这个 input 就当未修改,碰了就是改了,不需要判断是否一致,避免数据过时导致坑用户。判断到底改没改得交给后端做,让后端兜底。另外这种最好单独触发编辑,单独提交,避免意外修改。
    F7TsdQL45E0jmoiG
        17
    F7TsdQL45E0jmoiG  
       23 天前
    后端是兜底的
    vanchKong
        18
    vanchKong  
       23 天前
    问一嘴,前端校验都是手动校验吗?还是有什么库比较方便的进行校验
    laobobo
        19
    laobobo  
       23 天前
    这都说了多少次了,都校验!都校验!都校验!
    alanhe421
        20
    alanhe421  
       23 天前
    楼上说的多了,both
    lrh3321
        21
    lrh3321  
       23 天前
    都做,后端的校验不能省。前端不校验的话,别怪到时候判断不出是哪个字段有问题。
    wujianhua22
        22
    wujianhua22  
       23 天前
    1 、如果后端能够返回一定格式的校验结果数据,例如{"field1":"是必须项目","field2":"字符串长度必须大于 2"}等,这样你前端是可以使用异步校验,然后体现在画面上,那么你就可以不用写前端校验。但是一般来说,后端都不会这样返回。
    2 、有一些情况下需要预校验,例如输入手机号后,就需要校验该手机号是否已经存在。那么也会用到前端异步校验。
    3 、至于你说的更新的时候需要判断是否同一个手机号,这种一般判断是加上 [ID 主键] 和 [手机号] 一起判断,如果当前 Id 的手机号就是这个手机号,那就跳过,反之才去校验是否重复。
    ZENGQH
        23
    ZENGQH  
       23 天前
    22 楼.3 正解
    LuffyPro
        24
    LuffyPro  
    OP
       23 天前
    谢谢大家的回复,我看了下,大家好像都集中与前后端校验上,可能我问的方式不对。

    我的本意是,前端表单项中,没有发送数据变动的表单项数据有没有必要在编辑时也一起提交上来,打个比方,一个表单中有手机号码和名字,这时候只改了名字,手机号码没改,在提交时,有没有必要把没发生变化的手机号码也一起通过接口提交上来。

    因为如果没变化的手机号码也提交上来,并且手机号码必须确保唯一性,后端在校验号码唯一性时,除了判断手机号码是否已经被注册,还得再判断一遍是否等于当前用户的手机号码( true 的话支持继续修改),后面这个是否等于自己的手机号码的判断是因为前端把没有变化的手机号码也提交上来的,如果约定,数据不发生变化时不需要提交,那后端就只要判断该手机号码是否被注册就行了。

    感觉 15 楼明白我在说什么。 @old9
    Iakihsoug
        25
    Iakihsoug  
       23 天前
    都校验,双方做校验的目的不一样,不是同一件事
    Iakihsoug
        26
    Iakihsoug  
       23 天前
    @LuffyPro 这个其实应该算作产品设计上的问题,个人经验来说,特殊规则的编辑通常会单独做功能,而不是跟其他信息表单一起,比如手机号会有单独的修改手机号、图形验证和短信验证
    其他的信息一般都是校验后全量发到后端,否则如何判断用户是想要清空某个字段还是不修改呢? null?
    johnhuangemc2
        27
    johnhuangemc2  
       23 天前
    最佳实践是变了什么字段提交什么字段, 这样引发的问题最少, 比如说敏感字段脱敏展示.
    但一般这个不属于功能性需求, 产品不会提, 前端或后端单方面提出的话另一方不一定会配合.
    aababc
        28
    aababc  
       23 天前
    @LuffyPro 如果是 restful 那么就通过不同的行为来区分 put/patch/post ,比如可以使用 patch 来提交部分更新。
    zdkk
        29
    zdkk  
       23 天前
    都校验
    wqhui
        30
    wqhui  
       23 天前
    提交的所有内容都校验,或者最起码后端要把关键字段验了,不然别人直接调接口给你搞一堆乱七八糟的东西
    montaro2017
        31
    montaro2017  
       23 天前
    你的意思是修改的时候未修改的内容是否要一并提交
    建议是都提交
    1 是前端需要针对每个 input 进行监听比较是否修改,可能存在漏 input 的情况导致有的数据修改时候没提交上去
    2 是后端要对数据进行校验,如果未修改内容不提交,校验前得先判断是否为 null ,以 java 为例一般用 hibernate 注解来校验,如果为 null 就不太好用注解,得手动校验
    Arrowing
        32
    Arrowing  
       23 天前
    并没有冲突,前端校验是为了体验,后端校验是为了安全
    66beta
        33
    66beta  
       23 天前
    这有啥好抬杠的,前端可以不做,后端不能不做
    RRRSSS
        34
    RRRSSS  
       23 天前
    后端为了安全一定要做

    前端为了用户体验好,可以做

    就这么简单


    -----

    回到你的场景,前端什么都不用管啊,直接把这个表单所有字段发出去,这个 api 是 edit 功能,其实就是 UPDATE 操作,没什么了不得的。

    当然,你说的校验手机是否重复这种情况,对于后端开发,可校验,可不校验,看是什么系统,有没有特别的需求。

    但是,作为前端,是可以在提交之前告诉用户手机号是重复的。
    zhaogaz
        35
    zhaogaz  
       23 天前
    校验问题应该没啥可说的了。

    但是我觉得你可能问的是一个业务逻辑问题。
    一般清晰一点的业务,会把你这两个不同的修改拆开,姓名随便改;但是手机号修改逻辑稍微复杂一些,可能会单独去梳理这部分业务逻辑。在我看来是一个简单业务和复杂业务做一起了

    你现在困惑是,并且产品经理没有对细节做要求,你在不停地用业务逻辑给产品的不作为兜底。但是你不知道对不对。同时你的描述过于细节,让这帮程序员也陷入校验细节中。。。
    Al0rid4l
        36
    Al0rid4l  
       23 天前
    @LuffyPro 你这里认为的没有变化, 理解没错的话是前端视角认为的没有变化, 问题是, 前端认为的没有变化, 到了后端也可能有了变化...
    credo123
        37
    credo123  
       22 天前
    各干各的.
    后端必须效验. 前端也要效验.
    不冲突. 前后端要互不信任.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2477 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 15:15 · PVG 23:15 · LAX 08:15 · JFK 11:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.