当文件更改和页面重新加载时,从indexedDB中存储的文件句柄加载的文件不会更新

sg3maiej  于 2023-11-15  发布在  IndexedDB
关注(0)|答案(1)|浏览(209)

使用这里介绍的方法:
https://stackoverflow.com/a/65938910/3825996
我已经创建了一个网页,您可以在任何地方放置文件,内容将显示。放置后,文件的句柄存储在indexedDB中,当页面刷新时,最后一个文件将再次打开并显示。
我希望如果我更改文件并重新加载页面,会显示新内容,但实际上没有。然而,如果我拖放更改的文件,它将正确显示更改的内容。
在Chrome中,我也做了“清空缓存并硬重新加载”,但它仍然显示旧文件内容。
为什么会发生这种情况?文件句柄是否存储了完整的文件?我可以做些什么,以便在刷新后重新加载更改的文件?
下面是代码:(不作为HTML代码段工作)

<html>
<head></head>
<body>
    <div id="display"></div>
    <script>
        // stolen from https://www.npmjs.com/package/idb-keyval

        function promisifyRequest(request) {
            return new Promise((resolve, reject) => {
                request.oncomplete = request.onsuccess = () => resolve(request.result);
                request.onabort = request.onerror = () => reject(request.error);
            });
        }

        function createStore(dbName, storeName) {
            const request = indexedDB.open(dbName);
            request.onupgradeneeded = () => request.result.createObjectStore(storeName);
            const dbp = promisifyRequest(request);
            return (txMode, callback) => dbp.then((db) => callback(db.transaction(storeName, txMode).objectStore(storeName)));
        }

        let defaultGetStoreFunc;
        function defaultGetStore() {
            if (!defaultGetStoreFunc) {
                defaultGetStoreFunc = createStore('keyval-store', 'keyval');
            }
            return defaultGetStoreFunc;
        }

        function idbLoad(key, customStore = defaultGetStore()) {
            return customStore('readonly', (store) => promisifyRequest(store.get(key)));
        }

        function idbStore(key, value, customStore = defaultGetStore()) {
            return customStore('readwrite', (store) => {
                store.put(value, key);
                return promisifyRequest(store.transaction);
            });
        }

        function makeKey(domElement) {
            return 'lastOpened-' + domElement.tagName + "-" + domElement.id;
        }

        async function handleFile(domElement, file) {
            await idbStore(makeKey(domElement), file);
            const reader = new FileReader();
            reader.onload = function (e) {
                domElement.dispatchEvent(
                    new CustomEvent("handlefilecontent", { detail: e.target.result })
                );
            };
            reader.readAsText(file);
        }

        function dropHandler(ev) {
            ev.preventDefault();

            if (ev.dataTransfer.items) {
                [...ev.dataTransfer.items].forEach((item, i) => {
                    if (item.kind === "file") {
                        const file = item.getAsFile();
                        handleFile(ev.currentTarget, file);
                    }
                });
            } else {
                [...ev.dataTransfer.files].forEach((file, i) => {
                    handleFile(ev.currentTarget, file);
                });
            }
        }

        function dragOverHandler(ev) {
            ev.preventDefault();
        }

        async function checkLastOpened(domElement) {
            try {
                let file = await idbLoad(makeKey(domElement));
                if (file) {
                    handleFile(domElement, file)
                }
            } catch (error) {
                alert(error.name, error.message);
            }
        }

        function dragDropInitialize(domElement, callback) {
            domElement.addEventListener("drop", dropHandler)
            domElement.addEventListener("dragover", dragOverHandler)
            domElement.addEventListener("handlefilecontent", (ev) => { callback(ev.detail) })
            checkLastOpened(domElement)
        }

        dragDropInitialize(document.body, (content) => {
            document.getElementById("display").innerHTML = content
        })
    </script>
</body>

</html>

字符串

yks3o0rb

yks3o0rb1#

通过DataTransferItemgetAsFile()DataTransferfiles列表返回的对象都是File对象,它们并不等价于文件句柄,而是代表文件本身的数据--web平台API中的一个File基本上只是一个有名字的Blob
因此,当你调用idbStore()传递文件时,你实际上是在将文件的内容存储到数据库中。当存储发生时,实现将把文件的内容存储到数据库中。这就是为什么当你重新加载页面时,你看不到新的数据。

相关问题