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

使用zxing实现HTML端适配iPhone及Android手机条码扫描器的问题咨询

问题根因定位
  • iOS Safari对window.open触发的自定义协议跳转有严格的拦截规则,只有用户主动点击瞬间触发的跳转才会被放行,你代码里的逻辑被判定为非用户直接触发行为后会被直接拦截,无任何报错提示
  • iOS Safari在页面处于后台状态时,storage事件会被冻结,扫描完成切回原页面后事件不会触发,导致无法拿到扫描结果
  • iOS不允许未通过JS打开的页面调用window.close(),你代码头部的页面关闭逻辑完全失效,无法完成结果回传
  • 字符串形式的setTimeout执行逻辑在iOS的内容安全策略下会被拦截,导致storage监听无法按时移除
修复方案

1. 调整自定义协议跳转逻辑

区分iOS设备,统一用window.location.href跳转,避免window.open被拦截:

function getScan(){
    var href = window.location.href;
    var ptr = href.lastIndexOf("#");
    if(ptr>0){
        href = href.substr(0,ptr);
    }
    window.addEventListener("storage", onbarcode, false);
    // 替换字符串形式的setTimeout为函数形式
    setTimeout(() => {
        window.removeEventListener("storage", onbarcode, false);
    }, 15000);
    localStorage.removeItem("barcode");

    const ua = navigator.userAgent;
    if (ua.match(/iPhone|iPad|iPod/i) || ua.match(/Firefox/i)) {
        // iOS和火狐统一用location跳转,避免弹窗拦截
        window.location.href = "zxing://scan/?ret=" + encodeURIComponent(href + "#zx{CODE}");
    } else {
        window.open("zxing://scan/?ret=" + encodeURIComponent(href + "#zx{CODE}"));
    }
}

2. 兼容iOS的结果监听逻辑

新增页面切回前台的主动校验,不单独依赖storage事件:

// 新增pageshow监听,切回页面时主动取localStorage的扫描结果
window.addEventListener('pageshow', () => {
    const bc = localStorage.getItem('barcode');
    if (bc) {
        localStorage.removeItem('barcode');
        processBarcode(bc);
    }
});

3. 移除无效的页面关闭逻辑

修改头部的hash处理逻辑,删除iOS下不生效的window.close调用:

if(window.location.hash.substr(1,2) == "zx"){
    var bc = decodeURI(window.location.hash.substr(3));
    localStorage.setItem("barcode", bc);
    // 直接跳回原地址,无需尝试关闭页面
    window.location.href = window.location.href.split('#')[0];
}

注意:iOS端微信、钉钉等App的内置浏览器禁止跳转第三方自定义协议,如果你的业务场景在这类App内运行,需要改用前端直接调用相机识别条码的方案,不要依赖ZXing客户端跳转。

内容的提问来源于stack exchange,提问作者심도현

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 23:36:03