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

Firebase与JavaScript中Uncaught ReferenceError:函数未定义问题求助

解决ES模块作用域与Firebase Storage上传的冲突问题

核心问题本质

ES模块(type="module")的函数默认处于私有作用域,不会挂载到全局window对象,导致:

  • 非模块脚本(原webcam.js)无法访问模块中的sauvegarder函数
  • 模块脚本中的startRecording/stopRecording无法被HTML的onclick直接调用

以下是三种针对性解决方法,按需选择:


方案1:将webcam.js转为模块,挂载函数到全局

兼容原有onclick写法,适合不想大幅修改HTML的场景:

  1. 修改HTML脚本引入
<script type="module" src="firebase_using.js"></script>
<script type="module" src="webcam.js"></script>
  1. 导出firebase_using.js中的上传函数
// firebase_using.js
import { initializeApp } from "firebase/app";
import { getStorage, ref, uploadBytes } from "firebase/storage";

// 初始化Firebase(替换为你的配置)
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID"
};
initializeApp(firebaseConfig);

// 导出上传函数
export async function sauvegarder(videoBlob) {
  const storage = getStorage();
  const fileRef = ref(storage, `recordings/${Date.now()}.webm`);
  return uploadBytes(fileRef, videoBlob);
}
  1. 在webcam.js中导入并挂载全局函数
// webcam.js
import { sauvegarder } from './firebase_using.js';

// 原有的录屏逻辑
function startRecording() {
  // 你的启动录制代码
}

async function stopRecording() {
  // 原有的停止录制、生成blob逻辑
  const videoBlob = /* 你的录屏blob对象 */;
  
  // 调用Firebase上传
  try {
    await sauvegarder(videoBlob);
    console.log("视频上传成功");
  } catch (err) {
    console.error("上传失败:", err);
  }
}

// 将函数挂载到window,让onclick能访问
window.startRecording = startRecording;
window.stopRecording = stopRecording;

方案2:将sauvegarder挂载到全局,保留webcam.js非模块状态

适合不想修改webcam.js模块类型的场景:

  1. 修改firebase_using.js,挂载函数到全局
// firebase_using.js
import { initializeApp } from "firebase/app";
import { getStorage, ref, uploadBytes } from "firebase/storage";

// 初始化Firebase
const firebaseConfig = { /* 你的配置 */ };
initializeApp(firebaseConfig);

async function sauvegarder(videoBlob) {
  const storage = getStorage();
  const fileRef = ref(storage, `recordings/${Date.now()}.webm`);
  return uploadBytes(fileRef, videoBlob);
}

// 挂载到全局window对象
window.sauvegarder = sauvegarder;
  1. 在webcam.js中直接调用全局函数
// webcam.js(保持非模块)
async function stopRecording() {
  const videoBlob = /* 你的录屏blob */;
  try {
    await sauvegarder(videoBlob);
    console.log("上传成功");
  } catch (err) {
    console.error("上传失败:", err);
  }
}

方案3:使用事件监听替代inline onclick(推荐)

符合ES模块规范,不污染全局作用域:

  1. 修改HTML,给按钮添加ID
<button id="start-recording-btn">开始录制</button>
<button id="stop-recording-btn">停止录制</button>

<script type="module" src="firebase_using.js"></script>
<script type="module" src="webcam.js"></script>
  1. firebase_using.js保持方案1的导出逻辑

  2. 在webcam.js中绑定事件监听

// webcam.js
import { sauvegarder } from './firebase_using.js';

function startRecording() {
  // 你的启动录制代码
}

async function stopRecording() {
  const videoBlob = /* 你的录屏blob */;
  try {
    await sauvegarder(videoBlob);
    console.log("上传成功");
  } catch (err) {
    console.error("上传失败:", err);
  }
}

// 绑定点击事件
document.getElementById('start-recording-btn').addEventListener('click', startRecording);
document.getElementById('stop-recording-btn').addEventListener('click', stopRecording);

注意事项

  • 确保Firebase配置信息正确,且已在控制台开启Storage服务
  • 录屏生成的blob格式需符合Storage支持的类型(如webm、mp4)

内容的提问来源于stack exchange,提问作者Tsu'Na

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:17:17