实现JS图片视频预览功能报Uncaught DOMException错误如何解决
问题根因
你遇到的Uncaught (in promise) DOMException: Failed to load because no supported source was found报错由以下几个错误导致:
- 你在HTML的
<video>标签上已经写了空的src属性,又在JS里动态添加<source>子标签,浏览器会优先读取video标签上的空src,找不到可播放资源就抛出异常 - 全局只创建了一次
<source>标签,多次选择视频时重复追加、修改同一个source节点会导致解析异常 - 重置视频预览时,你错误地给外层容器
previewVideoContainer(div元素)设置src属性,完全没有清空video的实际播放地址 - 用FileReader把视频转成base64编码既浪费性能,大视频还会出现卡顿、加载失败问题,预览本地文件直接用
URL.createObjectURL()即可
修复方案
1. HTML调整(可选,简化结构)
删除<video>标签上的空src属性即可,不需要其他改动:
<div class="video-preview" id="videoPreview"> <video controls loop autoplay muted class="video-preview__video" id="video"></video> </div>
如果不想改HTML,JS里覆盖video的src属性也可以解决。
2. JS修复后的完整代码
// 图片预览逻辑(原本逻辑正常,保留即可) const inpFile = document.getElementById("inpFile"); const previewContainer = document.getElementById("imagePreview"); const previewImage = previewContainer.querySelector(".image-preview__image"); inpFile.addEventListener("change", function() { const file = this.files[0]; if (file) { const reader = new FileReader(); previewContainer.style.display = "block"; previewImage.style.display = "block"; reader.addEventListener("load", function() { previewImage.setAttribute("src", this.result); }); reader.readAsDataURL(file); } else { previewImage.style.display = null; previewImage.setAttribute("src", ""); previewContainer.style.display = "none"; } }); // 修复后的视频预览逻辑 const inpFile2 = document.getElementById('inpFile2'); const video = document.getElementById('video'); const previewVideoContainer = document.getElementById("videoPreview"); inpFile2.addEventListener('change', function() { const file = this.files[0]; // 先清空之前的播放资源,避免残留报错 video.removeAttribute('src'); while (video.firstChild) { video.removeChild(video.firstChild); } if (file) { previewVideoContainer.style.display = "block"; // 直接生成临时本地资源地址,不需要转base64 const videoUrl = URL.createObjectURL(file); // 直接给video设置src即可,不需要额外创建source标签 video.setAttribute('src', videoUrl); video.load(); // play返回promise,加catch避免自动播放被浏览器限制时抛错 video.play().catch(err => console.log('自动播放被阻止:', err)); } else { previewVideoContainer.style.display = "none"; } });
优化建议(可选)
如果想只用一个input同时支持选图片和视频,只需要把input的accept属性改成accept="image/*,video/*",然后在change事件里判断选中文件的type字段,分别走图片/视频的预览逻辑即可。
内容的提问来源于stack exchange,提问作者rustyrice23
相关产品推荐
相关产品推荐

