Bruce86 发表于 2024-5-23 08:29:14

9.1 离线存储图片

本帖最后由 Bruce86 于 2024-5-23 08:40 编辑

我做了一个移动端的 填报页面;由于使用人员,现场拍照使用时, 国外的网络不稳定,上传图片经常丢失等问题发生。 我想设计一个功能:用户点击“暂存”时,存储到 移动端本地数据库中; 有稳定网络的情况后,在点击“提交”,数据上传到到国内的服务器上。
界面:



遇到的问题:图片 在不联网的情况下,根本就无法保存到本地。一篇空白。而且 使用的 localstorage 本地存储 空间太小了,只有5mb,根本就放不下几张照片。

需求:想 改成 indexedDB的方式用来存储 图片数据。

杜清松-808916 发表于 2024-5-23 08:29:15

1.文件选择与本地暂存:用户选择照片后,将照片暂存到 IndexedDB。
2.检测网络状态:利用 navigator.onLine 和 window 事件监听网络状态。
3.网络恢复时批量上传:当检测到网络恢复时,读取 IndexedDB 中的照片并批量上传。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Local Store and Upload Images Later</title>
</head>
<body>
    <h1>Local Store and Upload Images Later</h1>
    <input type="file" id="fileInput" multiple>
    <button id="storeButton">Store Locally</button>
   
    <script>
      const dbPromise = indexedDB.open('photosDB', 1);

      dbPromise.onupgradeneeded = event => {
            const db = event.target.result;
            if (!db.objectStoreNames.contains('photos')) {
                db.createObjectStore('photos', { keyPath: 'id', autoIncrement: true });
            }
      };
      dbPromise.onsuccess = event => {
            console.log('Database opened successfully');
      };
      dbPromise.onerror = event => {
            console.error('Database error:', event.target.errorCode);
      };

      document.getElementById('storeButton').addEventListener('click', () => {
            const fileInput = document.getElementById('fileInput');
            const files = fileInput.files;

            const db = dbPromise.result;
            const tx = db.transaction('photos', 'readwrite');
            const store = tx.objectStore('photos');

            for (let file of files) {
                const reader = new FileReader();
                reader.onload = (event) => {
                  const data = event.target.result;
                  store.add({ fileName: file.name, data });
                };
                reader.readAsDataURL(file);
            }

            alert('Files have been stored locally.');
      });

      function uploadPhotos() {
            const db = dbPromise.result;
            const tx = db.transaction('photos', 'readonly');
            const store = tx.objectStore('photos');
            const request = store.getAll();

            request.onsuccess = event => {
                const files = event.target.result;

                files.forEach(file => {
                  const formData = new FormData();
                  formData.append('file', dataURIToBlob(file.data), file.fileName);

                  fetch('/upload', {
                        method: 'POST',
                        body: formData
                  })
                  .then(response => response.json())
                  .then(data => {
                        console.log('Success:', data);
                        // 删除已上传的文件
                        const delTx = db.transaction('photos', 'readwrite');
                        const delStore = delTx.objectStore('photos');
                        delStore.delete(file.id);
                  })
                  .catch(error => console.error('Error uploading file:', error));
                });
            };
      }

      function dataURIToBlob(dataURI) {
            const byteString = atob(dataURI.split(','));
            const mimeString = dataURI.split(',').split(':').split(';');
            const ab = new ArrayBuffer(byteString.length);
            const ia = new Uint8Array(ab);
            for (let i = 0; i < byteString.length; i++) {
                ia = byteString.charCodeAt(i);
            }
            return new Blob(, { type: mimeString });
      }

      window.addEventListener('online', uploadPhotos);
    </script>
</body>
</html>

Nathan.guo 发表于 2024-5-23 09:29:41

大佬可以先参考这篇帖子,实现离线填报功能~~

如何在Web应用中实现离线填报功能
https://gcdn.grapecity.com.cn/showtopic-167507-1-1.html
(出处: 葡萄城开发者社区)

Bruce86 发表于 2024-5-23 09:38:08

Nathan.guo 发表于 2024-5-23 09:29
大佬可以先参考这篇帖子,实现离线填报功能~~

如何在Web应用中实现离线填报功能


这部分已经实现了。现在是图片的存储无法实现。

Nathan.guo 发表于 2024-5-23 11:16:35

Bruce86 发表于 2024-5-23 09:38
这部分已经实现了。现在是图片的存储无法实现。

大佬,首先,我们离线填报想实现上传图片的话,是需要先将图片转为Base64进行存储的

其次根据咱们的场景,如果是移动端拍照,并且图片数量较多的话,建议使用HAC,因为再HAC中缓存的话,会存储的realm数据库


一看就会,超有用活字格技能:一百九十五、如何在HAC上实现离线/拍照/水印/GPS/NFC..
https://gcdn.grapecity.com.cn/showtopic-203094-1-1.html
(出处: 葡萄城开发者社区)


Bruce86 发表于 2024-5-23 13:44:06

Nathan.guo 发表于 2024-5-23 11:16
大佬,首先,我们离线填报想实现上传图片的话,是需要先将图片转为Base64进行存储的

其次根据咱们的场 ...

感谢郭工的支持,我先试试看是否可行。

Nathan.guo 发表于 2024-5-23 16:52:40

:hjyzw:

Bruce86 发表于 2024-5-23 17:01:05

杜清松-808916 发表于 2024-5-23 16:22
1.文件选择与本地暂存:用户选择照片后,将照片暂存到 IndexedDB。
2.检测网络状态:利用 navigator.onLin ...

请教一下大佬 ,这个怎么绑定到 活字格的按钮中去。

Nathan.guo 发表于 2024-5-23 18:28:56

大佬,我理解咱们把对应的JavaScript代码写好,再按钮命令中调用就好了呀~~

https://www.grapecity.com.cn/solutions/huozige/help/docs/command/javascriptcommand
页: [1]
查看完整版本: 9.1 离线存储图片