input输入框粘贴unicode零宽字符,前端踩坑和解决方案

在前端表单中,如果用户输入时是直接从其他地方如 excel 里复制的,就有可能包含这类看不见的零宽字符;据说从 iphone 手机的通讯录里复制的电话号码粘贴进excel中就有可能包含零宽字符。

当用户提交时,前端在控制台打印或者network里看提交的接口参数里也是看不到这类字符的

如果 input 输入框有限制最大输入长度 max-length,零宽字符也是会占用输入框的长度的。

另外输入框校验也会被影响。

如下图所示

前端解决办法

过滤零宽字符串

js 复制代码
str.replace(/[\u200b-\u200f\uFEFF\u202a-\u202e]/g, "");

正则表达式 /[\u200b-\u200f\uFEFF\u202a-\u202e]/g 的解释如下:

  • [\u200b-\u200f\uFEFF\u202a-\u202e] 表示 Unicode 范围,表示可能存在的多余空白字符的 Unicode 范围。
  • \u200b-\u200f 表示 Unicode 范围,表示可能存在的零宽空格(Zero-width space)的 Unicode 范围。
  • \uFEFF 表示 Unicode 字符,表示 U+FEFF 字符,表示字节顺序标记(byte order mark)的 Unicode 字符。
  • \u202a-\u202e 表示 Unicode 范围,表示可能存在的格式化片段标记(format variant)的 Unicode 范围。
  • /g 表示全局搜索,表示正则表达式会搜索字符串中所有符合条件的子串。

对于校验类影响-可在校验前过滤零宽字符串

以今天碰到的 react16 + antd V2. 为例

这里可以使用 getFieldDecorator 里的 getValueFromEvent 或者 normalize 参数

------>> antd官网

js 复制代码
<FormItem label="公司税号:">
    {getFieldDecorator('dutyParagraph', {
      initialValue: '',
      normalize: (value) => {
        value = value.replace(/[\u200b-\u200f\uFEFF\u202a-\u202e]/gi, '')
        return value;
      },
      rules: [
        {
          required: headEditFlag == '1',
          message: '请输入公司税号',
        },
        {
          pattern: new RegExp(/^[A-Za-z0-9]+$/, 'i'),
          message: '公司税号只能是数字和字母!'
        },
        {
          min: headEditFlag == '1' ? 6 : 0,
          message: "最少必须输入6个字符",
        },
        {
          max: 20,
          message: "最多可输入20个字符",
        },
      ],
    })(<Input placeholder='请输入公司税号' />)}
</FormItem>
js 复制代码
<FormItem label="公司税号:">
    {getFieldDecorator('dutyParagraph', {
      initialValue: '',
      getValueFromEvent: (e) => {
        let value = e.target.value || '';
        value = value.replace(/[\u200b-\u200f\uFEFF\u202a-\u202e]/gi, '')
        return value;
      },
      rules: [
        {
          required: headEditFlag == '1',
          message: '请输入公司税号',
        },
        {
          pattern: new RegExp(/^[A-Za-z0-9]+$/, 'i'),
          message: '公司税号只能是数字和字母!'
        },
        {
          min: headEditFlag == '1' ? 6 : 0,
          message: "最少必须输入6个字符",
        },
        {
          max: 20,
          message: "最多可输入20个字符",
        },
      ],
    })(<Input placeholder='请输入公司税号' />)}
 </FormItem>

常见的几种零宽字符有:

  • 零宽空格:U+200B
  • 零宽连接符:U+200D,常见的复杂Emoji表情即用到了该字符,用于表示多字符关系从而合成复杂新字符
  • 零宽非连接符:U+200C
  • 零宽非断空格符:U+FEFF
  • 左至右符:U+200E
  • 右至左符:U+200F
  • 蒙古文元音分隔符:U+180E

怎么能看见零宽字符?

直接复制到开发工具如 vscode 里,是可以直接看到这类字符的 unicode 码的。 如下所示

在 windows 记事本中-右键,选择 "显示 Unicode 控制字符",也可以‭看到这类特殊符号。

navicat 中查看mysql中的数据,也可以像记事本一样右键选择"显示 Unicode 控制字符",光标聚焦的时候也可以看到有特殊符号显示出来。

还有复制粘贴进网页、记事本、输入框中,移动光标的时候,也可以发现,这类字符也是需要靠光标移动的。 参考文档

相关推荐
尤水就下14 小时前
🔥预热:在线文档的 block 架构是如何实现的(未完待续...)
前端·javascript·架构
song50114 小时前
React Native for OpenHarmony 实战:三方库 react-native-parallax-scroll-view 的鸿蒙化适配指南
分布式·react native·react.js·transformer·harmonyos
全栈项目管理程序猿14 小时前
ArcGIS JS 基础教程(29):CSVLayer 表格点位图层
前端·javascript
骑着蜗牛撵大象32715 小时前
豆包 Seed 驱动的记账智能体:从拍票抽取到月报生成的全链路落地记录
java·前端·javascript·结构化输出·豆包seed·多模态识别·记账系统
溪语流沙15 小时前
【Web全栈进阶】前端世界观:现代工具链与框架为什么存在
前端·javascript·vue.js
kyriewen15 小时前
我逐个测了 JSON.stringify 的 7 个坑:第 1 个就在丢数据
前端·javascript·程序员
积流成海16 小时前
用代码实现哈希计算器:Web Crypto API 实战
前端·算法·哈希算法·哈希函数·盘子工具站
data analyse 45616 小时前
服务端访问日志聚合 PV 与 UV 怎么实现?日志采集与口径设计
大数据·前端·数据分析
song50116 小时前
React Native for OpenHarmony 实战:三方库 react-native-ratings 的鸿蒙化适配指南
javascript·react native·react.js·分类·harmonyos
JavaGuide16 小时前
DeepSeek Harness 重磅更新,Codex、Claude Code 子智能体进官方插件列表了,还有 Git 工作树和思考翻译!
前端·后端