
1. 从一张海报到浏览器里的 3D 模型AR.js 图片追踪到底怎么跑起来AR.js 图片追踪Image Tracking是 webAR 里最实用的一类能力你不需要装 App手机浏览器打开一个网页摄像头对准一张特定的图片页面上就会在图片的位置叠加一个 3D 模型而且模型会跟着图片移动、旋转、缩放。它适合谁适合想快速做营销物料、产品说明书、展会互动、教学卡片的开发者也适合前端同学想低成本试水 webAR 的场景。我这次要交付的是一个能直接扫码体验的 Demo一张图片作为识别目标识别成功后叠加一个 glTF 模型并且支持手势旋转缩放。整个链路分四步——准备 HTML 页面、生成图片特征文件.fset/.fset3/.iset、放入模型文件、真机验证。后端如果涉及模型下载、素材管理、鉴权这类调用我会用 TaoToken 统一 Key/API 通道来管理避免把密钥散落在前端。先说清楚一个前提手机浏览器调用摄像头必须走 HTTPS这是硬性要求HTTP 下 getUserMedia 会直接被拦。所以本地调试可以用 localhost真机验证一定要把页面部署到 HTTPS 域名下。下面从零开始每一步都给可复制的配置。2. TaoToken 前置准备统一 Key 与 API 通道别把密钥写进前端在动手写 AR 页面之前先把后端调用这条线理清楚。Demo 本身是纯前端但真实项目里往往需要从服务端拉取模型列表、按图片 ID 换取对应的 glTF 地址、记录识别次数、做素材鉴权。这些请求如果每个都单独配一套 Key维护起来很痛苦前端还容易泄露密钥。TaoToken 在这里的角色是统一入口一个 Key 走通模型对话、Coding Plan、控制台和 API Keys 管理。你需要先拿到两样东西——Base URL 和 API Key。Base URL 用https://taotoken.net/api注意这个地址不带任何查询参数Key 在控制台的 API Keys 页面创建。具体操作路径打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 进入控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 新建一个 Key。创建后立刻复制保存页面刷新后不再完整显示。如果你只是想先验证模型通道是否通可以直接用模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 发一条消息确认 Key 有效。长期做编码或 Agent 类任务可以看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。这里要强调一个安全习惯前端 HTML 里绝对不要硬编码 API Key。正确做法是前端请求你自己的后端后端再用 TaoToken 的 Key 去调用上游。下面这段是后端转发的最小示例Node.js 环境用环境变量存 Key// server.js —— 后端转发Key 只存在服务端 import express from express; const app express(); const TAOTOKEN_BASE https://taotoken.net/api; const TAOTOKEN_KEY process.env.TAOTOKEN_API_KEY; // 不要写死在代码里 app.get(/api/model-url, async (req, res) { const imageId req.query.imageId; // 这里可以按 imageId 查数据库返回对应 glTF 地址 const r await fetch(${TAOTOKEN_BASE}/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${TAOTOKEN_KEY}, }, body: JSON.stringify({ model: gpt-4o-mini, messages: [{ role: user, content: 返回图片${imageId}对应的模型文件名 }], }), }); const data await r.json(); res.json({ ok: true, data }); }); app.listen(3000, () console.log(listening on 3000));启动前设置环境变量export TAOTOKEN_API_KEY你的Key然后node server.js。这样前端只请求/api/model-url密钥不出服务端。如果你用的是 Claude Code 这类工具做辅助开发接入时同样填 Base URL、Key、Model ID 三件套缺一不可。3. 可复制配置HTML 页面 图片特征文件 模型三件套这一节是核心全部给可复制的片段。先看目录结构建议这样组织webAR-demo/ ├── index.html ├── aframe-master.min.js ├── aframe-ar-nft.js ├── gestures.js ├── nft/ │ └── smoking_boy/ │ ├── smoking_boy.fset │ ├── smoking_boy.fset3 │ └── smoking_boy.iset └── model/ └── smoking_boy/ └── scene.gltfindex.html完整代码如下注意a-nft的url不带扩展名指向 nft 目录下的文件名前缀!DOCTYPE html html head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1 titleAR.js 图片追踪 Demo/title script srcaframe-master.min.js/script script srcaframe-ar-nft.js/script script srcgestures.js/script style .arjs-loader { height: 100%; width: 100%; position: absolute; top: 0; left: 0; background-color: rgba(0, 0, 0, 0.8); z-index: 9999; display: flex; justify-content: center; align-items: center; } .arjs-loader div { text-align: center; font-size: 1.25em; color: white; } /style /head body stylemargin: 0; overflow: hidden; div classarjs-loaderdiv正在加载AR模型请稍候.../div/div a-scene vr-mode-uienabled: false; gesture-detector rendererlogarithmicDepthBuffer: true; embedded arjstrackingMethod: best; sourceType: webcam; debugUIEnabled: false; a-nft typenft urlnft/smoking_boy/smoking_boy smoothtrue smoothCount10 smoothTolerance.01 smoothThreshold5 a-entity gltf-modelmodel/smoking_boy/scene.gltf scale50 50 50 gesture-handlerminScale: 0.25; maxScale: 10 position100 0 -200 rotation-90 0 0 /a-entity /a-nft a-entity camerafov: 190/a-entity /a-scene /body /html图片特征文件生成有两种方式。Web 版最省事打开 NFT-Marker-Creator 的在线页面左侧放入你的目标图片点右侧 Generate等它跑完会下载三个文件.fset、.fset3、.iset把它们放进nft/smoking_boy/并保持文件名前缀一致。Node 版适合批量处理git clone https://github.com/Carnaux/NFT-Marker-Creator.git cd NFT-Marker-Creator npm install node app.js -i ./your-image.jpg # 处理结果在 output/ 目录三个文件复制到 nft/smoking_boy/选图有讲究识别度低、纯色块多、分辨率低的图片基本识别不出来。优先选纹理丰富、对比明显、有独特角点的图。训练文件越大等待越久耐心等。模型替换把model/smoking_boy/里的 glTF 换成你自己的保持scene.gltf命名或者同步改 HTML 里的gltf-model路径。Demo 里用的是.gltf格式其他格式没验证过建议先用 glTF 跑通。如果模型太大加载会慢可以先用简单模型验证链路。4. 真机验证从 HTTPS 部署到识别成功的完整动作配置齐了接下来验证。第一步把整个webAR-demo目录部署到支持 HTTPS 的静态服务器上。本地可以用npx serve起服务但真机必须 HTTPS所以推荐部署到任意带证书的静态托管。部署后确认所有资源路径正确尤其是nft/和model/的相对路径。第二步手机浏览器打开页面会先看到黑色加载层「正在加载AR模型请稍候...」。这一步在等特征文件和模型下载设备性能越差等得越久。加载完成后黑屏消失出现摄像头画面。第三步把手机对准你生成特征文件时用的那张图片。注意调整距离让图片在画面里占据适中大小——太远识别不到太近可能超出视野。识别成功后3D 模型会出现在图片位置上跟着图片移动。用双指可以旋转和缩放模型这是gestures.js提供的gesture-handler在起作用。验证成功的标志模型稳定贴在图片上移动手机时模型跟随旋转图片时模型同步旋转。如果模型位置偏移检查a-entity的position和rotation参数rotation-90 0 0是常见的让模型立起来的修正。如果模型太大或太小调scale。后端调用这条线也要验证打开浏览器开发者工具看/api/model-url请求是否返回 200返回体里是否有模型信息。如果后端用了 TaoToken确认请求头里的Authorization: Bearer Key正确Base URL 是https://taotoken.net/api。这一步通了说明你的 Key 和通道都正常。真机验证时建议用两台设备一台放目标图片一台开摄像头识别这样方便调试。另外注意光线太暗或反光都会影响识别率。5. 常见报错排查401、local proxy failed、reading choices、OAuth跑 Demo 时最容易卡在几个报错上逐个说清楚。401 Unauthorized后端调用 TaoToken 时出现基本是 Key 问题。检查三件事——Key 是否复制完整前后无空格、请求头是否是Authorization: Bearer Key、Base URL 是否是https://taotoken.net/api不要多加斜杠或路径。如果 Key 是在控制台新建的确认没有误删。用模型对话页面先测一下 Key 是否有效能排除大部分问题。local proxy failed这个报错通常出现在本地开发环境说明请求没走到目标地址被本地网络配置拦了。检查你的开发服务器是否正常启动、端口是否被占用、请求地址是否写错。如果是前端直连后端确认后端 CORS 配置允许当前来源。这个报错和 TaoToken 本身无关是本地链路问题。reading choices这是解析响应时的经典错误意思是代码在读取data.choices时data是 undefined 或结构不对。原因通常是请求失败但代码没判断状态码直接去取choices。修复方式是先判断response.ok再解析const r await fetch(url, options); if (!r.ok) { console.error(请求失败, r.status, await r.text()); return; } const data await r.json(); const content data?.choices?.[0]?.message?.content; if (!content) { console.error(响应结构异常, data); return; }OAuth 相关报错如果你用 Claude Code 或类似工具接入出现 OAuth 报错通常是认证方式没选对。这类工具接入时要填全三件套——Base URL、API Key、Model ID。Base URL 用https://taotoken.net/apiKey 用控制台创建的Model ID 按你实际使用的模型填。三者缺一或填错都会报认证失败。接入文档里有各工具的详细配置照着填即可。另外补充一个 AR 侧的高频问题页面一直卡在加载层。这通常是特征文件路径不对或文件缺失。检查nft/目录下三个文件是否齐全、文件名前缀是否和 HTML 里url一致、部署后能否直接访问到这些文件。用浏览器直接打开.fset的 URL能下载说明路径没问题。6. 把 Demo 变成可复用能力Key 管理与后续扩展Demo 跑通只是起点。真正落地时你会遇到多张图片对应多个模型、需要动态切换、需要统计识别数据这些需求。这时候统一 Key 管理的价值就体现出来了——所有后端调用走同一个通道换 Key、加额度、看用量都在一个控制台完成不用在多个服务间来回切换。具体做法前端只认图片 ID后端根据 ID 返回模型地址和特征文件地址同时用 TaoToken 的通道做鉴权和日志。这样新增一张识别图只需要在后端加一条映射前端不用改。模型文件建议放 CDN特征文件也可以一起放减少首屏加载时间。如果你后续要做更复杂的交互比如识别后触发模型对话、语音讲解可以直接复用同一套 Key。模型对话入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 需要长期跑编码或 Agent 任务就看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。API Keys 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。最后给一个实用技巧调试 AR 识别时先把debugUIEnabled打开能看到识别状态和特征点信息定位问题快很多。上线前再关掉。图片特征文件生成后建议本地留一份备份换服务器时直接复制不用重新训练。模型尽量压缩glTF 可以用工具做 Draco 压缩加载速度会明显提升。