前端计数器显示 200/200,用户按了发送,接口回内容超过 300 字上限。把文本复制到别处一数,实际是 203 个字符。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,前端用字符串的 length 计数,把这个代理对和部分组合符号算成两个。后端按字符集里的字符数统计,emoji 和带修饰的符号各算一个,两边自然对不上。
「字符计数不一致」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。别只看报错的最后一行,往上看几行,真正的起因通常在上面。
const count = [...textarea.value].length;
const seg = new Intl.Segmenter('zh', { granularity: 'grapheme' });
const n = [...seg.segment(textarea.value)].length;
同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。
具体做法是,计数改用 Array.from 或扩展运算符按码点拆分;要和数据库一致时按后端字符集规则再算一次,别只看码点;计数器改成剩余可输入字数,接近上限时提前截断粘贴。
最后用这个标准收尾,输入含 emoji 和组合符号的文本,前端计数与接口统计一致,边界值不再被后端拒绝。
