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

SvelteKit扫码Web应用:PC端可调用摄像头,移动端无法正常使用

扫码应用iPhone端无法启动摄像头问题解决

问题

基于Svelte/SvelteKit开发的扫码Web应用,PC端运行正常:点击启动按钮会请求摄像头权限,授权后可正常扫码,停止按钮能关闭摄像头。但iPhone端访问时,点击启动按钮无任何反应,不弹出权限请求弹窗,停止按钮也无效,控制台报错:Unhandled Promise Rejection: Camera streaming not supported by the browsers。使用相同Html5Qrcode库的在线示例在iPhone上可正常运行,怀疑是当前应用使用HTTP协议导致移动端摄像头权限被限制。

原因分析

你的猜测完全正确——移动端浏览器(尤其是Safari)对摄像头等敏感API的访问强制要求HTTPS环境,仅允许localhost、127.0.0.1这类本地回环地址或HTTPS协议的网站调用摄像头权限。如果你的开发环境使用HTTP(比如SvelteKit默认的npm run dev HTTP服务),iPhone Safari会直接阻止摄像头API调用,触发上述报错。

另外,你的start函数是异步函数,但调用html5Qrcode.start时未添加错误捕获,导致Promise未处理的拒绝,这也是控制台报错的直接原因之一。

解决方案

  1. 切换到HTTPS环境运行/部署

    • 开发阶段:可以给SvelteKit配置HTTPS(使用自签名证书),或用local-ssl-proxy等工具将本地HTTP服务转成HTTPS,让iPhone能通过HTTPS访问本地开发服务。
    • 生产部署:必须部署到支持HTTPS的平台(如Vercel、Netlify等,这类平台默认提供HTTPS证书)。
  2. 添加错误捕获逻辑
    在start和stop函数中加入try/catch块,处理摄像头调用失败的情况,避免未处理的Promise拒绝,同时给用户友好的错误提示。

修改后的代码

<script>
    import { Html5Qrcode } from "html5-qrcode";
    import { onMount } from "svelte";

    let scanning = false;
    let html5Qrcode;
    let result = "";
    let errorMsg = "";

    onMount(init);

    function init() {
        html5Qrcode = new Html5Qrcode('reader');
    }

    async function start() {
        errorMsg = "";
        try {
            await html5Qrcode.start(
                { facingMode: 'environment' },
                {
                    fps: 10,
                    qrbox: { width: 250, height: 250 },
                },
                onScanSuccess,
                onScanFailure
            );
            scanning = true;
        } catch (err) {
            errorMsg = "无法启动摄像头:" + err.message;
            console.error("摄像头启动失败:", err);
        }
    }

    async function stop() {
        try {
            await html5Qrcode.stop();
            scanning = false;
        } catch (err) {
            console.error("停止摄像头失败:", err);
        }
    }

    function onScanSuccess(decodedText, decodedResult) {
        console.log(decodedResult);
        result = decodedResult.decodedText;
        stop();
    }

    function onScanFailure(error) {
        // 忽略扫描失败的常规错误,避免控制台刷屏
        return;
    }
</script>

<div class="container mx-auto">
    <div style="width: 300px" id="reader"></div>
    {#if scanning}
        <button class="btn btn-success" on:click={stop}>停止扫码</button>
    {:else}
        <button class="btn btn-warning" on:click={start}>启动扫码</button>
    {/if}
    {#if errorMsg}
        <div class="text-xl text-red-600 mt-2">{errorMsg}</div>
    {/if}
    <div id="result" class="text-3xl text-red-500 mt-4">{result}</div>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:27:26