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

基于Firestore字段传递Firebase Storage视频报uploadVid未定义错误

错误成因

触发Uncaught ReferenceError: uploadVid is not defined的核心原因是作用域不匹配:

  • 你将uploadVid函数定义在window.onload的回调函数内部,属于该回调的局部函数,仅能在回调内部被访问
  • HTML中写的内联事件onchange="uploadVid(this.files);"执行时,默认在全局window作用域查找uploadVid函数,找不到对应引用就会抛出引用错误

另外你的代码还存在3个会导致后续运行异常的隐藏问题:

  1. 代码中直接调用formA.addEventListener,但从未定义过formA变量,提交表单时会触发新的引用错误
  2. storageRef.child('subjectSel.value')传入的是固定字符串,不会读取下拉框选中的实际科目值,所有视频都会被存在同一个路径下产生覆盖
  3. 新版Firebase Storage已废弃snapshot.downloadURL属性,直接读取该值拿不到文件的合法访问地址
修复方案

推荐使用JS原生绑定事件的方式替代HTML内联事件,无需暴露全局函数,写法更规范,同时修复上述所有隐藏问题:

  1. 移除HTML中文件输入框上的内联onchange属性
  2. 在window.onload回调内部补全文件输入框、表单元素的DOM引用,直接绑定对应事件
  3. 修正Storage存储路径、下载URL获取的逻辑错误,提交表单时同步把视频地址存入Firestore,方便后续跨页面调用

修正后的核心代码如下:

修正后的HTML部分(仅修改文件输入框行,其余代码保留)

<div class="txtb">
  <!-- 移除原有的内联onchange属性 -->
  <input type="file" id="file-ip-1" accept="video/mp4">
</div>

修正后的JS部分

window.onload = function() {
  var subjectSel = document.getElementById("subject");
  var bookSel = document.getElementById("book");
  var pageSel = document.getElementById("page");
  const IGLink = document.querySelector("#IG_link");
  // 补全缺失的DOM引用
  const fileInput = document.getElementById("file-ip-1");
  const videoPreview = document.getElementById('file-ip-1-preview');
  const formA = document.querySelector(".login-form");

  for (var x in subjectObject) {
    subjectSel.options[subjectSel.options.length] = new Option(x, x);
  }
  subjectSel.onchange = function() {
    pageSel.length = 1;
    bookSel.length = 1;
    for (var y in subjectObject[this.value]) {
      bookSel.options[bookSel.options.length] = new Option(y, y);
    }
  }
  bookSel.onchange = function() {
    pageSel.length = 1;
    var z = subjectObject[subjectSel.value][this.value];
    for (var i = 0; i < z.length; i++) {
      pageSel.options[pageSel.options.length] = new Option(z[i], z[i]);
    }
  }
  
  // 直接在JS中绑定文件选择事件,无需全局暴露函数
  fileInput.onchange = function(e) {
    const storageRef = firebase.storage().ref();
    const file = e.target.files[0];
    // 修正路径:使用实际选择的科目值,拼接时间戳+原文件名避免文件覆盖
    const videoRef = storageRef.child(`videos/${subjectSel.value}/${Date.now()}_${file.name}`);

    const task = videoRef.put(file)

    task.then(snapshot => {
      console.log(snapshot)
      // 修正:使用官方提供的getDownloadURL方法获取合法访问地址
      return snapshot.ref.getDownloadURL()
    }).then(url => {
      videoPreview.setAttribute('src', url)
      // 将视频地址暂存在DOM上,提交表单时一起存入Firestore
      videoPreview.dataset.url = url
    }).catch(err => {
      console.error('视频上传失败:', err)
    })
  }

  // 表单提交逻辑
  formA.addEventListener('submit', e => {
    e.preventDefault();
    const db = firebase.firestore();
    db.collection('videos').add({
      subject: subjectSel.value,
      book: bookSel.value,
      page: pageSel.value,
      IGLink: IGLink.value,
      // 同步存储视频地址,后续其他页面可直接从Firestore读取该地址拉取视频
      videoUrl: videoPreview.dataset.url
    });
  });
}

内容的提问来源于stack exchange,提问作者armory victory

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 03:48:09