Next.js 中无法加载 face-api.js 模型(如 ssd_mobilenetv1)通常源于路径解析错误——服务端环境不支持 fs 且静态资源必须通过 HTTP URI 访问,而非本地文件路径。本文详解如何将模型部署至 public/ 目录,并使用 loadFromUri 安全加载。
next.js 中无法加载 face-api.js 模型(如 `ssd_mobilenetv1`)通常源于路径解析错误——服务端环境不支持 `fs` 且静态资源必须通过 http uri 访问,而非本地文件路径。本文详解如何将模型部署至 `public/` 目录,并使用 `loadfromuri` 安全加载。
在 Next.js 应用中集成 face-api.js 进行前端人脸检测时,一个常见误区是直接复用 Node.js 环境下的文件系统(fs)逻辑或相对路径调用(如 load('/model'))。由于 Next.js 的混合渲染特性(SSR/SSG/CSR),*服务端组件或 getServerSideProps 中无法访问 fs,且 `faceapi.nets..load()默认尝试解析为绝对 URL,而非静态资源路径**,从而抛出类似Failed to parse URL from /model/ssd_mobilenetv1_model-weights_manifest.json` 的运行时错误。
Next.js 将 public/ 目录作为静态资源根目录,所有其中的文件均可通过 / 开头的路径被浏览器直接请求(例如 http://localhost:3000/model/tiny_face_detector_model-weights_manifest.json)。因此,必须使用 loadFromUri() 并传入可公开访问的完整 URI 字符串。
将 face-api.js 所需模型文件(.json + .bin)统一放入项目根目录下的 public/model/:
your-nextjs-app/├── public/│ └── model/│ ├── ssd_mobilenetv1_model-weights_manifest.json│ ├── ssd_mobilenetv1_model.bin│ ├── tiny_face_detector_model-weights_manifest.json│ └── tiny_face_detector_model.bin├── src/│ └── app/│ └── page.tsx
⚠️ 注意:不要在代码中使用 fs.existsSync() —— 它在浏览器端不可用,在服务端则无法访问 public/(该目录仅对客户端 HTTP 请求生效)。
为适配不同部署环境(本地开发、Vercel、自定义域名),推荐通过环境变量注入基础 URL:
// .env.localNEXT_PUBLIC_BASE_PATH=http://localhost:3000# 生产环境示例(Vercel):# NEXT_PUBLIC_BASE_PATH=https://your-app.vercel.app
// lib/faceApiLoader.tsimport * as faceapi from 'face-api.js';export async function loadFaceApiModels(): Promise<void> { // ✅ 安全获取客户端可访问的基础路径 const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ''; const modelUrl = `${basePath}/model`; console.log('Loading models from:', modelUrl); try { // ✅ 使用 loadFromUri(非 load),确保走 fetch 请求 await faceapi.nets.ssdMobilenetv1.loadFromUri(modelUrl); await faceapi.nets.tinyFaceDetector.loadFromUri(modelUrl); await faceapi.nets.faceLandmark68Net.loadFromUri(modelUrl); await faceapi.nets.faceRecognitionNet.loadFromUri(modelUrl); console.log('✅ All face-api.js models loaded successfully'); } catch (err) { console.error('❌ Failed to load face-api.js models:', err); throw err; }}
由于 face-api.js 依赖 canvas 和 fetch,必须在 useEffect 或事件处理器中执行加载逻辑,且确保组件已挂载到 DOM:
// app/page.tsx'use client';import { useEffect } from 'react';import { loadFaceApiModels } from '@/lib/faceApiLoader';export default function HomePage() { useEffect(() => { // ✅ 只在客户端执行模型加载 loadFaceApiModels().catch(console.error); }, []); return <div className="p-4">Face detection ready.</div>;}
遵循以上步骤,即可彻底解决 Next.js 中 face-api.js 模型加载失败问题,实现稳定、可部署的人脸识别功能。