将上传文件的路径存储在客户端或浏览器外部以供离线使用

Store the path to uploaded file on client-side or the file outside the browser for offline

有没有办法存储用户想要上传但没有互联网连接(它是 PWA)的文件的路径,并在连接恢复时重新上传?或者可能不存储路径,而是将文件保存在浏览器存储之外,在用户机器上的某个地方(即使需要用户接受才能允许浏览器访问 read/write 文件),但我不确定如果它甚至被允许这样做。

目前,我将整个文件作为 base64 存储在 IndexedDB 中,但在读取大文件(大约 100MB)时,它 crashing/slowing 在浏览器下。另外,我不想让浏览器存储过载。

有几件事需要考虑。

将需要上传的数据存储在 IndexedDB 中,然后在稍后读取将是最广泛支持的方法。不过,正如您所说,这意味着占用额外的浏览器存储空间。可能有帮助的一件事是首先跳过在 Base64 中对文件进行编码的步骤,因为在所有现代浏览器中,IndexedDB 很乐意直接为您存储字节 as a Blob.

一种更现代的方法,但目前不受非 Chromium 浏览器支持的方法是使用文件系统访问 API。如 this article 中所述,一旦获得用户许可,就可以将句柄保存到 IndexedDB 中的文件,然后稍后读取该文件(假设底层文件在此期间没有更改)。这样做的好处是不会在 IndexedDB 中复制文件内容,从而节省存储空间 space。这是从文章中借用的代码片段:

import { get, set } from 'https://unpkg.com/idb-keyval@5.0.2/dist/esm/index.js';

const pre = document.querySelector('pre');
const button = document.querySelector('button');

button.addEventListener('click', async () => {
  try {
    // Try retrieving the file handle.
    const fileHandleOrUndefined = await get('file');    
    if (fileHandleOrUndefined) {      
      pre.textContent =
          `Retrieved file handle "${fileHandleOrUndefined.name}" from IndexedDB.`;
      return;
    }
    // This always returns an array, but we just need the first entry.
    const [fileHandle] = await window.showOpenFilePicker();
    // Store the file handle.
    await set('file', fileHandle);    
    pre.textContent =
        `Stored file handle for "${fileHandle.name}" in IndexedDB.`;
  } catch (error) {
    alert(error.name, error.message);
  }
});

无论您如何存储文件,在可用时使用 Background Sync API(同样,目前仅限于 Chromium 浏览器)在网络再次可用时处理自动上传会很有帮助。