上传文件到本地

发布于:2025-08-30 ⋅ 阅读:(21) ⋅ 点赞:(0)

需求背景:在开发静态页面的过程或者一个简单的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>


网站公告

今日签到

点亮在社区的每一天
去签到