当前位置: 首页 > news >正文

上传文件到本地

需求背景:在开发静态页面的过程或者一个简单的demo的时候需要一个上传文件的功能,要求文件能新增、删除、回显、下载等功能;localStorage和sessionStorage虽然能存储一部分信息,但是无法存储file对象文件信息。本文也是也是存储在本地,但是可以如同存储在数据库一样,随意获取file对象数据

demo代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>上传文件到本地</title><style>#uploadBox{width: 400px;height: 300px;margin: auto;}/* 上传文件 */#box {width: 100%;height: 150px;border: 2px dashed #aaa;display: flex;align-items: center;justify-content: center;cursor: pointer}ul {margin-top: 10px;padding-left: 20px}#examineFile,#customsFile {display: none;}</style>
</head><body><div id="uploadBox"><div id="box">点击或拖拽上传 PDF / 图片</div><input id="in" type="file" multiple accept="image/*,application/pdf" style="display:none"><ul id="ShowFilelist"></ul></div><script>/* ---------- 1. 建库(原生) ---------- */const DB_NAME = 'FileDB';const STORE = 'files';const VER = 1;let db;const openDB = () => new Promise((resolve, reject) => {const req = indexedDB.open(DB_NAME, VER);req.onerror = () => reject(req.error);req.onsuccess = () => { db = req.result; resolve(); };req.onupgradeneeded = () => {const store = req.result.createObjectStore(STORE, { keyPath: 'id', autoIncrement: true });store.createIndex('name', 'name', { unique: false });};});/* ---------- 2. 工具函数 ---------- */const addFile = f => new Promise((resolve, reject) => {const tx = db.transaction([STORE], 'readwrite');const store = tx.objectStore(STORE);const req = store.put({ name: f.name, data: f, type: f.type });req.onsuccess = () => resolve();req.onerror = () => reject(req.error);});const getAll = () => new Promise((resolve, reject) => {const tx = db.transaction([STORE], 'readonly');const req = tx.objectStore(STORE).getAll();req.onsuccess = () => resolve(req.result);req.onerror = () => reject(req.error);});const delFile = id => new Promise((resolve, reject) => {const tx = db.transaction([STORE], 'readwrite');const req = tx.objectStore(STORE).delete(id);req.onsuccess = () => resolve();req.onerror = () => reject(req.error);});/* ---------- 3. 交互 ---------- */const box = document.getElementById('box');const inp = document.getElementById('in');const list = document.getElementById('ShowFilelist');box.onclick = () => inp.click();box.ondragover = e => e.preventDefault();box.ondrop = e => { e.preventDefault(); save([...e.dataTransfer.files]); };inp.onchange = () => save([...inp.files]);/* ---------- 4. 保存 & 刷新列表 ---------- */async function save(files) {await openDB();for (const f of files) {if (!/^(image\/|application\/pdf)/.test(f.type)) continue;await addFile(f);}refresh();}async function refresh() {await openDB();const fileList = await getAll();list.innerHTML = '';console.log("获取所有本地文件", fileList);fileList.forEach(f => {const li = document.createElement('li');li.textContent = f.name;const btn = document.createElement('button');btn.textContent = '删除';btn.className = "ml10"btn.addEventListener('click', () => del(f.id));   // ✅ 纯 JS 绑定li.appendChild(btn);list.appendChild(li);});}async function del(id) { await delFile(id); refresh(); }refresh(); // 页面加载即显示</script>
</body></html>

http://www.dtcms.com/a/357112.html

相关文章:

  • LeetCode Hot 100 第8天
  • 医疗 AI 的 “破圈” 时刻:辅助诊断、药物研发、慢病管理,哪些场景已落地见效?
  • 174. Java 注释 - 声明注释类型
  • 《AI智脉速递》2025 年 8 月22 日 - 29 日
  • VS2022+QT6.7+NetWork(TCP服务器多客户端助手)
  • Rust 登堂 之 深入Rust 类型(六)
  • 如何打造团队协作型 IP,而非单人依赖型?
  • BugKu Web渗透之file_get_contents
  • Kotlin中回调函数的使用示例
  • Git-Git和TortoiseGit的安装以及使用
  • 云渲染云推流助力WebGL应用网页端无负担推流,摆脱终端加载缓慢问题
  • 无恶意软件勒索:Storm-0501如何转向云原生攻击
  • Linux829 shell:expect interact “ “ set
  • 知识卡片html5动态网页源码
  • CRYPT32!CryptMsgUpdate函数分析之CRYPT32!PkiAsn1Decode函数的作用是得到pci
  • ros2--topic/话题--接口
  • tauri打包失败
  • 太阳光模拟器在卫星研发与测试中的应用
  • wav音频转C语言样点数组
  • 嵌入式Linux设备树驱动开发 - dtsof驱动
  • shell学习(二)
  • Sharding-JDBC 使用方法
  • 为什么不能创建泛型数组?
  • C++并发编程-17. 线程安全的链表
  • Unity EventTrigger 动态添加事件
  • flume事务机制详解:保障数据可靠性的核心逻辑
  • 项目中为什么使用SpringBoot?
  • 晨控CK-FR102ANS与欧姆龙NX系列PLC配置EtherNet/IP通讯连接手册
  • 如何规划一年、三年、五年的IP发展路线图?
  • Android 端 QGroundControl 控制 PC 端Gazebo Sim 仿真无人机