You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
    • 确认测试手机已经给浏览器开放短信读取权限
    • 短信里的域名必须和你实际访问页面的域名完全一致,路径部分的斜杠不能多写或者漏写

你在非TS版CRA项目里能正常运行,是因为JS转译不会做属性校验,otp配置会被完整保留;如果CRA没有开启React 18严格模式,useEffect重复执行的问题也不会暴露。


内容的提问来源于stack exchange,提问作者Raj Dutta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:15:48