TypeScript+Vite环境下WebOTP自动填充功能失效如何解决
Vite + TypeScript 环境下WebOTP自动填充失效修复方案
核心问题排查与修复
useEffect 写法错误导致监听冲突
你当前的useEffect没有传入第二个依赖参数,默认会在组件每次重渲染时重复触发OTP监听请求;加上React 18 开发环境严格模式会执行两次组件挂载流程,旧的监听请求没有被正确终止的话,会和新请求冲突,导致接口一直不返回结果。
直接替换成下面的写法即可:useEffect(() => { if (!('OTPCredential' in window)) return; const ac = new AbortController(); navigator.credentials .get({ otp: { transport: ['sms'] }, signal: ac.signal, }) .then((otp: any) => { setState(otp.code); }) .catch((err) => { if (err.name !== 'AbortError') console.log(err); }); // 组件卸载时主动终止未完成的监听 return () => ac.abort(); }, []); // 空依赖数组保证仅在组件挂载时执行一次原来的代码在
then和catch里重复调用ac.abort()是多余的,统一在清理函数里处理即可。类型声明缺失导致编译时配置被抹除
Vite 基于 esbuild 做TS转译时,会直接丢弃它认为不合法的未声明属性,你虽然创建了polyfills.d.ts,但如果没有正确声明OTP相关的接口,navigator.credentials.get里传入的otp配置会在编译阶段被删掉,自然无法触发API。
在你的polyfills.d.ts里补充以下声明即可:interface OTPCredential extends Credential { code: string; } interface CredentialRequestOptions { otp?: { transport: Array<'sms'>; }; }补充后确认
tsconfig.json的include配置已经覆盖了你的typings目录,参考配置:{ "include": ["src/**/*", "typings/**/*"] }环境与格式校验
做完上面两步如果还不生效,逐一核对以下规则:- WebOTP API仅在安全上下文生效,本地开发用
localhost访问,部署环境必须配置HTTPS - 不要用隐身模式测试,部分浏览器隐身模式默认禁用凭证管理API
- 确认测试手机已经给浏览器开放短信读取权限
- 短信里的域名必须和你实际访问页面的域名完全一致,路径部分的斜杠不能多写或者漏写
- WebOTP API仅在安全上下文生效,本地开发用
你在非TS版CRA项目里能正常运行,是因为JS转译不会做属性校验,otp配置会被完整保留;如果CRA没有开启React 18严格模式,useEffect重复执行的问题也不会暴露。
内容的提问来源于stack exchange,提问作者Raj Dutta
相关产品推荐
相关产品推荐

