大多数VIN错别字都没有打出来。它们是从电子邮件、pdf、经销商门户网站和SMS线索中粘贴的,这些线索将17个字符的代码包装在标签、空格或整车简介中。如果你的输入只听change并修剪最后的字符串,用户已经看到一个红色的错误闪烁,而粘贴仍在建立。
浏览器给了你一个更好的钩子paste事件和clipboardData。处理好这个事件,https://www.iissbbs.com你就可以正常化以前反应状态,在校验位验证之前,以及在任何NHTSA调用之前。
这篇文章是一个实用的指南VIN安全的焊膏处理:读取剪贴板文本,去除不属于VIN的垃圾,阻止多值转储,并保持可访问的键盘粘贴工作。它通过在剪贴板点击字段时运行来补充普通的修剪和大写帮助器。
浆糊到底传递了什么
A ClipboardEvent可以公开HTML、纯文本和文件。对于VIN字段,您几乎总是只需要纯文本。
function plainTextFromPaste(event: ClipboardEvent): string {
const data = eventclipboardData;
if (!data) return "";
return datagetData("text/plain") || datagetData("text") || "";
}
忽视text/html。经销商电子邮件爱情<span>1HG</span>包装纸;HTML粘贴路径重新引入了标签和实体,https://www.ycsjb.com然后您必须撤销。也忽略截图中的文件粘贴:OCR属于一个单独的流程,而不是一个普通的VIN框。
对VIN字符集进行消毒
ISO风格的vin使用A-Z和0-9,除了I、O和q结构并且保守认为:
大写字母
删除空白和常用分隔符(-, :, )
丢弃明显的标签(VIN, Veh, #)
拒绝或截断超过17个有用的字符,而不是默默地从一个段落中挑出错误的17个
const VIN_CHAR = /[A-HJ-NPR-Z0-9]/i;
export function sanitizeVinPaste(raw: string): {
candidate: string;
rejectedExtra: boolean;
hadLabelNoise: boolean;
} {
const upper = rawtoUpperCase();
const hadLabelNoise = /\bVIN\b|\bVEHICLE\b/test(upper);
let cleaned = upper
replace(/\bVIN\b\s*[#:-]?\s*/g, "")
replace(/[^A-Z0-9]/g, "");
// Drop illegal VIN letters entirely (I, O, Q) rather than mapping them
cleaned = cleaned
split("")
filter((ch) => VIN_CHARtest(ch))
join("");
const rejectedExtra = cleanedlength > 17;
const candidate = cleanedslice(0, 17);
return { candidate, rejectedExtra, hadLabelNoise };
}
不要自动映射O到0或者I到1粘贴处理程序内部。这属于一个明确的“你的意思是?”UX,如果你愿意的话。无声的音译产生了自信的错误解码,这比明确的验证错误更糟糕。
连接粘贴处理器
防止默认插入,整理,然后将候选项写入输入。这避免了字段显示200个字符的转储而验证器尖叫的情况。
export function onVinPaste(
event: ClipboardEvent,
apply: (vin: string, meta: { rejectedExtra: boolean }) => void,
): void {
const raw = plainTextFromPaste(event);
if (!raw) return;
eventpreventDefault();
const { candidate, rejectedExtra } = sanitizeVinPaste(raw);
apply(candidate, { rejectedExtra });
}
在反应中:
<input
name="vin"
autoComplete="off"
spellCheck={false}
inputMode="text"
onPaste={(e) => {
onVinPaste(enativeEvent, (vin, meta) => {
setVin(vin);
setHint(
metarejectedExtra
? "Paste looked longer than a VIN; used the first 17 characters"
: null,
);
});
}}
/>
spellCheck={false}问题:浏览器喜欢在VIN外观的令牌上使用红色下划线。autoComplete="off"减少浏览器将旧地址片段放入框中的可能性。
多行和多车辆识别号粘贴
来自电子表格的剪贴板有效负载通常包括制表符和换行符。预先决定产品政策:
粘贴形状 推荐UX
一个令牌,消毒后长度为17 默默接受
更长的斑点,前17个清晰 接受+简短提示
几个17字符的令牌 用“粘贴一个VIN”拒绝
消毒后清空 保持字段不变+错误
export function detectMultiVin(raw: string): boolean {
const tokens = raw
toUpperCase()
split(/[\s,;]+/)
map((t) => treplace(/[^A-Z0-9]/g, ""))
filter((t) => tlength >= 11);
const vinLike = tokensfilter((t) => tlength === 17);
return vinLikelength > 1;
}
如果detectMultiVin是真的,斯基普sanitizeVinPaste的切片行为,并要求用户粘贴一段代码。默默地从列表中取出第一个VIN,这就是市场表格中错误的汽车是如何被解码的。
可访问性和安全性说明
不要打电话navigatorclipboardreadText()除非必须,否则贴上;事件的clipboardData这就足够了,避免了额外的权限提示
保持Ctrl/Cmd+V工作;永远不要禁用全站点粘贴
宣布消毒剂提示aria-live="polite"因此屏幕阅读器用户知道为什么值会改变
从不记录原始剪贴板内容;仅日志长度和布尔标志
运行相同的消毒剂blur对于键入而不是粘贴的用户,因此两条路径在解码前会汇合