凌晨两点,我盯着浏览器里的表单<form>标签发呆。那个登录框的代码“提交”按钮怎么点都没反应,控制台报错像弹幕一样刷屏——后来发现只是网页忘记写name属性。这种蠢事,表单写表单的代码人多少都干过。
表单的网页本质是“让用户把数据交给你”。但很多人只把它当成一排输入框加一个按钮。表单你看电商的代码结算页,一个地址表单能拆成七八个字段,网页每个字段的表单type、placeholder、代码required都得斟酌。网页比如手机号,表单用type="tel"在手机上会弹出数字键盘,代码但PC端没什么区别。真正关键的是pattern属性,写个正则^1[3-9]\d{ 9}$,能挡住一半手滑输错的用户。
最容易被忽视的是label标签。很多人直接写<input placeholder="请输入用户名">就完事。可屏幕阅读器读不到placeholder,视障用户就懵了。正确写法是<label for="username">用户名</label><input id="username">——for和id必须对上,这算表单的“无障碍地基”。我自己测试过,去掉label后,用NVDA读页面,焦点一进输入框就报“编辑框,空白”,用户根本不知道要填什么。
再说说提交方式。GET会把表单数据拼在URL后面,适合搜索框——刷新页面还能保留关键词。但登录密码用GET?地址栏直接暴露明文,那场面太美我不敢看。POST才是正解,数据放请求体里,浏览器地址栏干干净净。有个土办法区分:你把表单action指向一个测试接口,提交后看浏览器地址栏,若问号后跟着一堆参数,那就是GET,赶紧换成POST。
验证逻辑也分层次。前端用required、maxlength这些属性做基础校验,但别全信它们——按F12删掉属性就能绕过。真正的防线在后端。我见过一个注册页,前端校验密码必须含数字和字母,后端却只查了长度,结果用户提交“123456”照样成功。这种漏洞,懂点技术的人都能钻空子。所以写表单时,前端校验只是用户体验,后端校验才是安全底线。
有个细节我最近才注意到:autocomplete属性。浏览器自动填充是双刃剑,填快递地址很方便,但填信用卡号就危险了。给敏感字段加上autocomplete="off",或者用autocomplete="new-password"让浏览器别自作主张。之前给一个内部系统做表单,默认autocomplete开着,结果测试同事的浏览器自动把他家的收货地址填进了工单系统,笑归笑,细想挺吓人。
样式方面,别光顾着美化。input:focus的描边颜色要明显,但别用大红大绿——色弱用户看着费劲。字号至少16px,否则iOS上聚焦会自动放大页面,用户一填表就得来回缩放。我常用fieldset给一组相关字段分组,比如“账单地址”和“配送地址”各包一个,视觉上清晰,提交的数据结构也整齐。
最后说个反直觉的坑:表单里只有一个输入框时,按回车会自动提交。但如果有两个输入框,回车可能没反应。解决方法是加一个隐藏的<input type="submit" style="display:none">,或者监听keydown事件手动处理。我上周就给一个搜索框加了这个,不然用户按回车没动静,还以为是页面卡了。
写表单不是堆标签,是跟用户的手指和眼睛打交道。每个属性都有它的脾气,你摸透了,表单才好用。下次调试时,先看看控制台有没有红色报错,再检查name和id是不是成双成对——八成问题就出在这儿。
```