【问题标题】:Save FormData to Indexdb将表单数据保存到 Indexeddb
【发布时间】:2021-02-03 16:48:00
【问题描述】:

以下代码是将数据保存到目标数据库的最终操作。

const onFileUpload = (e) => {
  const files = Array.from(e.target.files);
  const formData = new FormData();
  formData.append('attachable_type', attachableType);
  formData.append('attachable_id', attachableId);

  if (files.length > 0) {
    const file = files[0];
    formData.append('file', file);

    upload(dispatch, {
      body: formData,
    }).then(() => {});
  }
};

现在我正在构建一个离线应用程序,当没有可用的互联网时,我想将此请求保存到 indexdb。我有整个设置。我只想知道如何将FormData 实例保存到 indexdb,以便以后可以从 indexdb 中获取它并将其发送到服务器进行永久存储。我需要一些想法。我尝试了一些谷歌,但我没有看到以下问题的任何直接答案。我正在使用idb npm 插件。我将使用以下更新函数作为与数据库对话的接口。

export async function update(attrs) {
  const db = await createAppDB();

  const tx = db.transaction('attachments', 'readwrite');
  const store = tx.objectStore('attachments');

  store.put(attrs);

  await tx.done;
}

【问题讨论】:

    标签: javascript service-worker indexeddb


    【解决方案1】:

    您可以通过Body.formData() 方法提取FormData,然后通过获取该FormData 的条目来检索其内容并将这些条目存储到IDB:

    (async () => {
      // in ServiceWorker while disconnected
      const request = buildRequest();
      // extract the FormData
      const fd = await request.formData();
      const serialized = {
        url: request.url,
        method: request.method,
        mode: request.mode,
        body: [ ...fd ]
        // you may need more fields from request
      };
      // you can now store the entries in IDB
      // here we just log it
      console.log( "stored", serialized );
    
      // and to build back the Request
      const retrieved = { ...serialized };
      const new_body = new FormData();
      for( let [ key, value ] of retrieved.body ) {
        new_body.append( key, value );
      }
      retrieved.body = new_body;
      const new_request = new Request( retrieved );
      // fetch( new_request );
      // remember to remove from IDB to avoid posting it multiple times
      console.log( "sent", [...new_body] );
    } )();
    
    
    // returns the same kind of Request object a ServiceWorker would intercept,
    // whose body is a FormData
    function buildRequest() {
      const fd = new FormData();
      fd.append( "some-key", "some-data" );
      fd.append( "the-file", new Blob( [ "hey" ] ), "file.txt" );
      return new Request( "", { method: "POST", body: fd } );
    }

    太糟糕了,我们不能只将 POST 请求放在缓存 API 中,这样会更干净...

    【讨论】:

    • 是的,这就是我解决问题的方法。感谢您的回答。
    • retrivedBody = cursor.value.body.reduce((fd,e) => (fd.append(...e),fd), new FormData());
    【解决方案2】:

    据我所知,您不能将任何 FormData 直接存储到 IndexedDB 中。就我而言,我必须为离线应用实现照片上传。我将图像以 base64 格式与其他一些数据一起保存到 IndexedDB 中,然后在互联网连接恢复后将它们上传到服务器上。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-21
      • 2017-03-06
      • 1970-01-01
      • 2016-10-15
      • 1970-01-01
      • 1970-01-01
      • 2018-06-01
      • 1970-01-01
      相关资源
      最近更新 更多