OTP自动填充触发AbortError:接收SMS前请求被取消,求排查
可能的原因及解决方案
以下是针对你遇到的navigator.credentials.get立即触发AbortError问题的排查方向和解决办法:
非HTTPS环境限制
Web Credentials API(包括OTP自动填充功能)强制要求页面运行在HTTPS环境下(localhost本地调试除外)。如果你的测试环境使用HTTP协议,浏览器会直接中止API请求,触发AbortError。
解决方案:切换到HTTPS环境测试,或使用localhost进行本地调试。AbortController实例被提前回收
当前代码中AbortController是then回调内部的局部变量,可能被JavaScript垃圾回收机制提前回收,导致信号意外中止。
解决方案:将AbortController提升为组件状态,延长其生命周期:
const TestPage = () => { const [otpValue, setOtpValue] = useState(""); const [ac, setAc] = useState(null); const handleSendOTP = () => { loginServices .SendVerifyCodeLogin("09361651719") .then((res) => { if (res) { if (navigator && navigator.credentials) { const newAc = new AbortController(); setAc(newAc); navigator.credentials .get({ otp: { transport: ["sms"] }, signal: newAc.signal, }) .then((otp) => setOtpValue(otp.code)) .catch((err) => { console.log(newAc.signal); console.log(err); }); } toast.success(res.result); } }) .catch(console.error); }; // 组件卸载时中止请求(可选) useEffect(() => { return () => ac?.abort(); }, [ac]); // 其余代码不变 };
浏览器自动填充权限被禁用
部分浏览器默认禁用OTP自动填充功能,或用户手动关闭了相关权限,会导致API请求被直接中止。
解决方案:检查浏览器设置,确保「自动填充」或「密码与表单」相关功能处于启用状态。用户交互校验限制
虽然代码在按钮点击回调中调用API,但某些浏览器对用户交互的校验更严格(要求API调用必须直接绑定到用户手势事件,不能嵌套在Promise回调中)。
解决方案:调整逻辑顺序,先调用navigator.credentials.get,再发送OTP请求:
const handleSendOTP = () => { if (navigator && navigator.credentials) { const ac = new AbortController(); navigator.credentials .get({ otp: { transport: ["sms"] }, signal: ac.signal, }) .then((otp) => setOtpValue(otp.code)) .catch((err) => { console.log(ac.signal); console.log(err); }); } loginServices .SendVerifyCodeLogin("09361651719") .then((res) => res && toast.success(res.result)) .catch(console.error); };
- 输入框配置冲突
确保输入框没有readonly、disabled等冲突属性,且推荐将type设为tel(更贴合OTP场景):
<input type="tel" className="bg-slate-300" autoComplete="one-time-code" value={otpValue} onChange={(e) => setOtpValue(e.target.value)} />
内容的提问来源于stack exchange,提问作者Arash Forghanbin
相关产品推荐
相关产品推荐

