maxlength仅对text、search、url、tel、email、password和textarea有效,对number等类型无效;需HTML+JS双校验,后端必须重校验且注意UTF-8长度计算。

maxlength 属性只对部分 input 类型生效
直接写 maxlength="10" 并不能在所有表单控件上起作用。它只对 text、search、url、tel、email、password 和 textarea 有效;对 number、date、file、checkbox 等类型完全无效——浏览器会静默忽略该属性。
常见错误现象: 看似写了,用户仍可输入任意位数数字; 虽然能截断,但邮箱格式校验(如缺少 @)优先级更高,用户可能根本输不到第 50 个字符就被拦住。
移动端软键盘行为也受此影响:iOS 达到上限后常禁用数字键,Android 则可能仍允许粘贴超长内容,必须额外监听 paste 事件。
textarea 的 maxlength 不是“全兼容”
虽然现代浏览器普遍支持 textarea 的 maxlength,但旧版 Safari(iOS 9–10)、部分 Android WebView 会忽略它。更关键的是,maxlength 计算的是 Unicode 码点数,不是字节数:一个中文、一个 emoji(如 ??)、一个英文都算 1 个长度单位;换行符 \n 算 1 个,\r\n 在某些浏览器里算 2 个。
所以仅靠 HTML 属性不够稳妥,建议双保险:
- HTML 层面写
- JS 层面监听
input和paste事件,实时截断:el.value = el.value.slice(0, 200) - 避免用
el.textLength获取长度——它非标准,且语义模糊;统一用el.value.length
绕过 maxlength 太容易,后端必须重校验
前端 maxlength 是纯体验层控制,删掉属性、禁用 JS、用 curl 或 Postman 发请求,都能轻松绕过。服务端不校验等于没设。
后端校验时注意三点:
- PHP 必须用
mb_strlen($str, 'UTF-8'),不能用strlen()(后者按字节计,中文会出错) - Node.js 中
req.body.field.length可用,但若 body 是 urlencoded 编码,空格被转成+,需先解码 - MySQL 的
VARCHAR(100)是按字符数定义的,和前端maxlength="100"对齐即可,但字段要留余量(如设为 120),防 emoji 编码转换或 CRLF 差异导致插入失败
动态改 maxlength 容易引发光标错乱
直接操作 element.maxLength = 50 或 element.setAttribute('maxlength', '50') 看似简单,但在受控组件(React/Vue)或 iOS Safari 中,可能导致光标跳到末尾、输入中断、甚至卡死。
更可靠的做法是:
- 不在 DOM 层硬改
maxlength,而是通过状态控制值(value),在onInput或onChange中截断字符串 - 若必须改属性,记得同步调用
element.setSelectionRange(cursorPos, cursorPos)修复光标位置 - 避免在
input事件中反复赋值触发新事件,加标记或防抖(如if (isTruncating) return)
真正难的不是“怎么设”,而是“设完之后用户还能不能自然地编辑、粘贴、删改”。很多边界情况(比如在中间粘贴、用输入法打一半拼音再删)只有真机测试才能暴露。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











