Next.js 中无法通过 load() 加载 face-api.js 模型,根本原因在于其服务端渲染(SSR)机制与模型路径解析冲突;需改用 loadFromUri() 并确保模型置于 public/model/ 下,通过客户端可访问的 URL 加载。
next.js 中无法通过 `load()` 加载 face-api.js 模型,根本原因在于其服务端渲染(ssr)机制与模型路径解析冲突;需改用 `loadfromuri()` 并确保模型置于 `public/model/` 下,通过客户端可访问的 url 加载。
在 Next.js 应用中集成 face-api.js 进行前端人脸检测时,开发者常遇到如下运行时错误:
Error: Failed to parse URL from /model/ssd_mobilenetv1_model-weights_manifest.json
该错误并非模型文件缺失或路径错误所致,而是源于 faceapi.nets.xxx.load(path) 方法的底层行为:它默认尝试以 Node.js 的 fs 方式读取本地文件(适用于纯服务端环境),但在 Next.js 的混合渲染(SSR + CSR)场景下,此方法会在服务端执行,而 public/ 目录仅在客户端可通过 HTTP 访问,服务端无法直接解析 /model/xxx.json 为有效 URL。
✅ 正确做法是:强制使用基于浏览器 Fetch 的 URL 加载方式 —— loadFromUri(),并确保模型资源通过 Web 可达路径提供。
模型存放位置
将所有 face-api.js 模型文件(如 ssd_mobilenetv1_model-weights_manifest.json, ssd_mobilenetv1_model.bin, tiny_face_detector_model-weights_manifest.json 等)统一放入项目根目录下的 public/model/ 文件夹中。
✅ 正确路径示例:/public/model/ssd_mobilenetv1_model-weights_manifest.json
❌ 错误路径示例:/src/model/ 或 /app/model/(不可被浏览器直接请求)
客户端安全加载(关键!)
faceapi.nets.xxx.loadFromUri() 仅支持在浏览器环境中运行(依赖 fetch),因此必须确保调用发生在客户端(如 useEffect 中、或 typeof window !== 'undefined' 判断后)。同时,推荐使用环境变量动态构造基础 URL,便于开发/生产环境切换:
// utils/faceApiLoader.tsimport * as faceapi from 'face-api.js';export async function loadFaceApiModels(): Promise<void> { // 确保仅在浏览器中执行 if (typeof window === 'undefined') return; // 从环境变量获取基础路径(支持部署子路径) const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ''; const modelUrl = `${basePath}/model`; try { console.log('Loading SSD MobileNetV1 model from:', modelUrl); await faceapi.nets.ssdMobilenetv1.loadFromUri(modelUrl); console.log('✅ SSD MobileNetV1 loaded'); console.log('Loading Tiny Face Detector model from:', modelUrl); await faceapi.nets.tinyFaceDetector.loadFromUri(modelUrl); console.log('✅ Tiny Face Detector loaded'); } catch (err) { console.error('❌ Failed to load face-api.js models:', err); throw err; }}
NEXT_PUBLIC_BASE_PATH=http://localhost:3000
? 提示:若部署到子路径(如 /my-app/),请设为 NEXT_PUBLIC_BASE_PATH=/my-app;生产环境可配合 next.config.js 的 assetPrefix 统一管理。
// components/FaceDetector.tsx'use client'; // 必须声明为 Client Component
import { useEffect } from 'react';import { loadFaceApiModels } from '@/utils/faceApiLoader';
export default function FaceDetector() {useEffect(() => {loadFaceApiModels().catch(console.error);}, []);
return
Face detection canvas will render here...;}### ⚠️ 注意事项- ❌ 不要使用 `fs.existsSync()` 或 `require()` 加载模型 —— 它们在浏览器中无效,且在 SSR 阶段会报错;- ❌ 避免在服务端组件(Server Components)或 `getServerSideProps` 中调用模型加载逻辑;- ✅ 所有 `face-api.js` 模型加载、推理操作必须严格限定在客户端生命周期内(`useEffect`、事件回调等);- ✅ 建议预加载关键模型,并添加 loading 状态与错误 fallback,提升用户体验;- ? 若仍报 404,请直接在浏览器访问 `http://localhost:3000/model/ssd_mobilenetv1_model-weights_manifest.json` 验证静态资源是否可公开访问。通过以上配置,你将彻底解决 Next.js 中 face-api.js 模型加载失败的问题,实现稳定、可部署的人脸检测功能。