如何在两个HTML页面间传递本地视频文件并实现跨页面播放
解决方案
核心问题:浏览器跳转页面后会完全销毁原页面的所有内存上下文,你之前获取的File对象、生成的Blob URL都和原页面绑定,跳转后自然失效,常规的全局变量、导出导入自然行不通。
方案1:单页模拟跳转(最简单,无兼容问题)
直接放弃真实页面跳转,把两个页面的功能合并到同一个HTML文件,用CSS控制显示隐藏,所有数据都在同一个上下文里,完全不用考虑传值问题。
示例代码结构:
<!-- 原page1内容 --> <div id="page1"> <label for = "movies">Select your movies:</label> <input type = "file" id = "movies" multiple/><br> <button id = "start">Load movies and play first one</button> </div> <!-- 原page2内容,默认隐藏 --> <div id="page2" style="display:none"> <video id = "video" controls></video> </div> <script> let localMovies; document.getElementById('start').addEventListener('click', () => { localMovies = document.getElementById("movies").files; if(!localMovies.length) return; // 切换显示状态,模拟跳转 document.getElementById('page1').style.display = 'none'; document.getElementById('page2').style.display = 'block'; // 直接播放 const movieURL = URL.createObjectURL(localMovies[0]); const videoTag = document.getElementById("video"); videoTag.src = movieURL; // 播放结束后释放内存 videoTag.onended = () => URL.revokeObjectURL(movieURL); }) </script>
方案2:必须跨页面的情况,用IndexedDB存储File对象
IndexedDB支持直接存储File/Blob类型数据,且同域名下的页面都可以访问,完全满足跨页传文件的需求。
修改后的page1.js
function loadMovies() { const selectedItems = document.getElementById("movies"); const localMovies = selectedItems.files; if (!localMovies.length) return; // 打开IndexedDB const dbOpen = indexedDB.open('movieStorage', 1); dbOpen.onupgradeneeded = e => { const db = e.target.result; db.createObjectStore('movies', { keyPath: 'id' }); }; dbOpen.onsuccess = e => { const db = e.target.result; const tx = db.transaction('movies', 'readwrite'); const store = tx.objectStore('movies'); // 存储文件列表 store.put({ id: 'selectedMovies', files: Array.from(localMovies) }); tx.oncomplete = () => { db.close(); // 存储完成再跳转 location.href = "page2.html"; }; }; }
修改后的page2.js
function startMovie() { const dbOpen = indexedDB.open('movieStorage', 1); dbOpen.onsuccess = e => { const db = e.target.result; const tx = db.transaction('movies', 'readonly'); const store = tx.objectStore('movies'); const getRequest = store.get('selectedMovies'); getRequest.onsuccess = () => { const localMovies = getRequest.result.files; const movieURL = URL.createObjectURL(localMovies[0]); const videoTag = document.getElementById("video"); videoTag.src = movieURL; // 用完释放内存 videoTag.onended = () => URL.revokeObjectURL(movieURL); db.close(); }; }; }
注意事项
- 原有代码里的小问题如
url要大写为URL、标签未闭合、函数缺少闭合大括号等,你可以自行调整 - 如果用户选中的文件体积非常大,IndexedDB存储会有短暂延迟,可加个加载提示提升体验
- 播放完成后记得调用
URL.revokeObjectURL()释放内存,避免页面占用过高
内容的提问来源于stack exchange,提问作者John Mcguyver
相关产品推荐
相关产品推荐

