外贸询盘表单产品型号字段:disabled 还是 readonly,以及提交后销售端能不能拿到型号

0
0

产品型号字段要买家看得见、核对得了,又不希望被随手改写,同时提交后销售端必须收到型号。本文按可验证的后果排序:先看 disabled 会让型号不随表单提交,再确认 readonly 只适用于文本类控件、对 select 无效,然后说明 readonly 与 disabled 都会让 required、pattern 这类浏览器校验失效,最后把浏览器端限制与服务器端校验分开,并给出一个标注为假设的走查示例。

先看提交结果:disabled 会让型号在提交数据里消失

型号字段的属性选择,第一个要看的不是它长什么样,而是买家点提交之后,销售端到底收不收得到这个型号。这一条决定了后面所有取舍有没有意义。

按 MDN 对 disabled 属性的说明,这个布尔属性一旦存在,元素就不可变、不可聚焦,而且不会随表单一起提交;用户既不能编辑,也不能聚焦该控件及其表单控件后代。 同一份文档在对比 disabled 与 readonly 时写得更直接:只读控件仍可运作、仍可聚焦,而禁用控件无法获得焦点、不随表单提交,并且在启用之前通常不作为控件运作。

把这两条落到询盘场景:如果表单只靠这个型号控件传送型号,而它被设成 disabled,买家在页面上仍然看得到型号,但提交出去的表单数据里不会带上这个字段。销售端收到的询盘就是缺型号的——不是型号显示错了,而是这一项根本没有到达。

所以属性选择的第一判断依据应该是提交结果,而不是控件外观。外观上 disabled 和 readonly 都可能被样式处理成灰色或浅色,看起来差不多;但一个会把型号从提交数据里拿掉,另一个不会。先确认这一点,再谈其他。

如果型号字段是买家从产品页带过来的,还需要顺带确认这个值是怎么进入表单的。表单元素本身代表的是包含交互控件、用于提交信息的文档区段,提交方式由 method 等属性控制,其中 post 会把表单数据作为请求体发送,get 则把数据以 ? 分隔符附加到 action 地址上。 这一段只说明提交通道本身的行为,不涉及型号值应该由谁写入。

MDN reference

MDN reference

readonly 能保住提交,但要先确认控件类型支持它

既然 disabled 会把型号从提交数据里拿掉,readonly 就成了更自然的候选:它同样让用户无法编辑控件,但控件仍然随表单提交。

但 readonly 不是万能的。MDN 明确列出它支持的控件范围:文本类表单控件,包括 text、search、tel、url、email、password、date、month、week、time、datetime-local、number 这些 input 类型,以及 textarea。 同一份文档也明确写出它不适用的情况:readonly 对其他元素不相关,包括 select 和 button;对非文本类 input 也不适用,包括 hidden、range、color、checkbox、radio、file、submit、image、reset、button。

这条边界对型号字段很关键。如果型号在表单里是一个下拉选择(select),那么加 readonly 不会产生只读效果——这个属性对 select 根本不适用。此时需要换一种呈现方式,例如把型号改成文本输入或纯文本展示,再决定它是否随表单提交。

还有一点需要提前知道:readonly 属性的值只能通过脚本动态修改。 这意味着如果型号需要在页面加载后由脚本写入,写入动作本身是可行的;但这属于实现细节,不改变“readonly 不等于防篡改”这个结论,下一节会接着说明。

MDN reference

只读或禁用之后,required 和 pattern 这些校验还管用吗

很多团队在型号字段上加了 required 或 pattern,以为这样就完成了校验设计。但如果这个字段同时是 readonly 或 disabled,这些属性并不会按预期工作。

MDN 的说明是:因为只读字段的值无法被用户交互改变,required 对同时指定 readonly 的输入不产生效果。 对 disabled 的说明类似:因为禁用字段的值无法被改变,required 对同时指定 disabled 的输入不产生效果;并且由于元素变得不可变,pattern 等大多数其他属性在控件启用之前也不产生效果。

更一般地说,禁用元素的值无法获得焦点、无法被用户更新,并且不参与约束校验;只读元素的值同样无法被用户更新,也不参与约束校验。

把这几条合起来看,结论是:型号字段的校验责任不能落在 required 或 pattern 上。这两个属性在只读或禁用状态下都不生效,它们既不能保证型号存在,也不能保证型号格式正确。

那校验应该放在哪里?OWASP 的输入校验备忘单给出的定位是:输入校验在应用使用数据之前检查数据是否满足应用要求,可以降低畸形数据、无效业务操作和过度资源消耗的风险。 同一份备忘单在常见陷阱里写得很清楚:客户端校验可被绕过,即使浏览器对相同字段做了检查,也应在服务器端校验;客户端校验的用途是即时反馈。

对型号字段来说,这意味着两件事要分开:浏览器端的 readonly 或 disabled 只是界面限制,它决定买家能不能在页面上改这个值;服务器端校验才是数据进入业务系统前的检查。前者不能替代后者。

如果型号是从固定选项里选出来的,备忘单还给出了一条具体规则:固定选项类输入应校验其是否精确属于允许集合,包括从下拉菜单提交的值。 备忘单对处理方式的要求是:拒绝无效请求并给出清晰错误,不要带着部分校验过的数据继续处理;只把预期的输入字段绑定到应用对象。

需要说明的是,本文不给出具体产品型号取值、字段命名或后端实现方式,这些应由企业依据自己的产品线与系统确定。

OWASP reference

一个假设的型号字段实现走查

以下内容为假设的演示场景,不代表任何真实站点、客户或实测结果。 下面通过假设走查把前面的判断串起来。这个示例是虚构的演示,不代表任何真实站点、客户或实测结果。

以下内容为假设的演示场景,不代表任何真实站点、客户或实测结果。 假设某产品页的型号字段是文本输入,型号值由页面带入。按前面的规则,这个字段采用 readonly 展示:买家能看到并核对型号,控件仍随表单提交,销售端能收到这个值。

以下内容为假设的演示场景,不代表任何真实站点、客户或实测结果。 假设该表单里,型号改成了下拉选择。这时 readonly 不适用,需要换一种只读呈现方式,而不是在 select 上加 readonly 属性。

以下内容为假设的演示场景,不代表任何真实站点、客户或实测结果。 提交之后,核对销售端收到的型号与页面展示是否一致。这一步是工程核验,不是浏览器属性本身能保证的结果。

走查的结论是:属性选择要跟着提交结果和控件类型走,而不是跟着外观走。readonly 能保住提交,但它只适用于文本类控件;disabled 会丢掉提交;两者都不承担校验责任。

如果你还在处理询盘表单的其他环节,站内《网站询盘表单:字段、反垃圾、路由与回传》处理的是字段清单、去重与 CRM 分配,与本文的控件属性选择不是同一个决策对象。

相关阅读:询盘表单字段与线索路由

评论 (0)

还没有评论,来发表第一条吧。

请先登录后再发表评论。