maxlength 是最直接有效的校验方式,但仅覆盖原生输入;需配合 javascript 的 input 事件(用 [...str].length 处理代理对)和 compositionend 防误截,pattern 仅用于提交校验,后端必须用相同逻辑重复校验。

maxlength 是最直接有效的校验方式,但仅靠它无法覆盖粘贴、中文输入法组合、代理对(如 emoji)等场景。必须配合 JavaScript 才能实现真正可控的字符数限制。
用 maxlength 做基础拦截
浏览器原生支持 maxlength,对 <input> 和 <textarea></textarea> 都生效,输入超过设定值时自动截断或拒绝输入。
- 它按 Unicode 码点计数,普通中文、英文、数字都算 1 个字符
- 但某些 emoji(如 ?✨)是代理对(surrogate pair),会被计为 2 个码点,实际显示为 1 个字形
- IE9+ 和所有现代浏览器均支持,无需 polyfill
- 注意:
maxlength不影响剪贴板粘贴行为——用户仍可粘贴超长内容,部分浏览器会静默截断,部分则允许完整粘贴后才触发限制
监听 input 事件做实时修正
当需要统一处理粘贴、拖拽、IME 输入等场景时,必须用 JavaScript 主动控制。
- 绑定
input事件比keyup更可靠,能捕获所有输入来源(包括语音、手写、粘贴) - 截断后务必调用
setSelectionRange(),否则光标会跳到开头或错位 - 对代理对敏感的场景(如含 emoji 的评论框),不能直接用
.length判断,应改用[...str].length或Array.from(str).length - 示例逻辑:
const input = document.getElementById('myInput'); const MAX = 20; input.addEventListener('input', () => { const str = input.value; const actualLen = [...str].length; if (actualLen > MAX) { input.value = str.slice(0, MAX); input.setSelectionRange(MAX, MAX); } });
用 pattern + title 做提交级语义校验
pattern 不限制输入过程,只在表单提交时触发验证,适合“允许输入但拒绝提交”的宽松策略。
- 必须包裹在
<form></form>内,且调用form.reportValidity()或用户点击type="submit"才会生效 - 正则需完整匹配,例如限制 1–10 字符:
pattern=".{1,10}",注意开头结尾隐含^和$ -
title属性内容会作为错误提示显示,但无法自定义样式或位置 - 该方式不防绕过,仅作辅助提示,绝不能替代
maxlength或服务端校验
后端必须重复校验字符长度
前端所有限制都可被禁用 DevTools、curl 或直接发请求绕过。
- 服务端收到数据后,必须用相同逻辑(如 Unicode 码点计数)检查长度,不能只依赖字节数或
strlen() - 特别是 Node.js 的
Buffer.byteLength(str, 'utf8')和[...str].length结果可能不同,选哪个取决于业务定义——“字符数”还是“存储上限” - 若数据库字段是
VARCHAR(20),且使用 utf8mb4,一个 emoji 占 4 字节,但只算 1 个字符;此时要明确:限制的是“显示字符数”还是“入库安全长度”
input.value 可能为空或只有拼音,这时用 input 事件截断会误伤。稳妥做法是监听 compositionend 后再校验,或加简单防抖。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











