Next.js中HTML script标签无法读取外部JS文件的问题
解决Next.js中外部JS文件加载及摄像头调用问题
问题根源分析
- 静态资源路径错误:Next.js要求外部静态资源(如JS文件)必须放在项目根目录的
public文件夹下,否则无法被正确访问。你的myscript.js如果没放在public里,自然找不到。 - script标签写法问题:HTML中
<script>标签不建议用自闭合形式(<script src="..." />),应写成<script src="myscript.js"></script>,部分浏览器对自闭合脚本标签的解析存在问题。 - JS代码拼写错误:
document.getElementByID是错误写法,正确的是document.getElementById(注意ID里的D需小写),这个错误会导致无法获取video元素,即便脚本加载成功也无法正常运行。
修复步骤
1. 放置静态资源到正确位置
将myscript.js移动到项目根目录的public文件夹下(没有的话直接新建一个)。
2. 修正page.js中的script标签
修改page.js代码,使用标准脚本标签写法:
export default function Live() { return ( <html> <body> <video id="webCam" autoPlay width="600" height="600"></video> <a download>Take Picture</a> <script src="/myscript.js"></script> </body> </html> ); }
注意脚本路径前要加/,表示从public根目录开始访问。
3. 修正myscript.js中的拼写错误
console.log("in"); const webCamEle = document.getElementById("webCam"); // 修正ID为Id navigator.mediaDevices.getUserMedia({ video: true }) .then((stream) => { webCamEle.srcObject = stream; }) .catch((error) => { console.error(error); });
更符合Next.js规范的实现方式
在Next.js中,更推荐用客户端组件的useEffect钩子执行客户端代码,无需依赖外部脚本,维护性更强:
"use client"; // 标记为客户端组件 import { useEffect, useRef } from "react"; export default function Live() { const videoRef = useRef(null); useEffect(() => { if (!videoRef.current) return; const startCamera = async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ video: true }); videoRef.current.srcObject = stream; } catch (error) { console.error("摄像头调用失败:", error); } }; startCamera(); // 组件卸载时停止摄像头,避免资源泄漏 return () => { if (videoRef.current?.srcObject) { videoRef.current.srcObject.getTracks().forEach(track => track.stop()); } }; }, []); return ( <div> <video ref={videoRef} autoPlay width="600" height="600"></video> <a download>Take Picture</a> </div> ); }
内容的提问来源于stack exchange,提问作者Bradan Craig
相关产品推荐
相关产品推荐

