找回密码
 立即注册

QQ登录

只需一步,快速开始

Bruce86

注册会员

11

主题

44

帖子

183

积分

注册会员

积分
183
Bruce86
注册会员   /  发表于:2024-5-23 08:29  /   查看:1756  /  回复:8
80金币
本帖最后由 Bruce86 于 2024-5-23 08:40 编辑

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



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

需求:想 改成 indexedDB的方式用来存储 图片数据。
附件: 您需要 登录 才可以下载或查看,没有帐号?立即注册

最佳答案

查看完整内容

1.文件选择与本地暂存:用户选择照片后,将照片暂存到 IndexedDB。 2.检测网络状态:利用 navigator.onLine 和 window 事件监听网络状态。 3.网络恢复时批量上传:当检测到网络恢复时,读取 IndexedDB 中的照片并批量上传。

8 个回复

倒序浏览
最佳答案
最佳答案
杜清松-808916
初级会员   /  发表于:2024-5-23 08:29:15
来自 6#
1.文件选择与本地暂存:用户选择照片后,将照片暂存到 IndexedDB。
2.检测网络状态:利用 navigator.onLine 和 window 事件监听网络状态。
3.网络恢复时批量上传:当检测到网络恢复时,读取 IndexedDB 中的照片并批量上传。
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Local Store and Upload Images Later</title>
  7. </head>
  8. <body>
  9.     <h1>Local Store and Upload Images Later</h1>
  10.     <input type="file" id="fileInput" multiple>
  11.     <button id="storeButton">Store Locally</button>
  12.    
  13.     <script>
  14.         const dbPromise = indexedDB.open('photosDB', 1);

  15.         dbPromise.onupgradeneeded = event => {
  16.             const db = event.target.result;
  17.             if (!db.objectStoreNames.contains('photos')) {
  18.                 db.createObjectStore('photos', { keyPath: 'id', autoIncrement: true });
  19.             }
  20.         };
  21.         dbPromise.onsuccess = event => {
  22.             console.log('Database opened successfully');
  23.         };
  24.         dbPromise.onerror = event => {
  25.             console.error('Database error:', event.target.errorCode);
  26.         };

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

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

  33.             for (let file of files) {
  34.                 const reader = new FileReader();
  35.                 reader.onload = (event) => {
  36.                     const data = event.target.result;
  37.                     store.add({ fileName: file.name, data });
  38.                 };
  39.                 reader.readAsDataURL(file);
  40.             }

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

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

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

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

  53.                     fetch('/upload', {
  54.                         method: 'POST',
  55.                         body: formData
  56.                     })
  57.                     .then(response => response.json())
  58.                     .then(data => {
  59.                         console.log('Success:', data);
  60.                         // 删除已上传的文件
  61.                         const delTx = db.transaction('photos', 'readwrite');
  62.                         const delStore = delTx.objectStore('photos');
  63.                         delStore.delete(file.id);
  64.                     })
  65.                     .catch(error => console.error('Error uploading file:', error));
  66.                 });
  67.             };
  68.         }

  69.         function dataURIToBlob(dataURI) {
  70.             const byteString = atob(dataURI.split(',')[1]);
  71.             const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  72.             const ab = new ArrayBuffer(byteString.length);
  73.             const ia = new Uint8Array(ab);
  74.             for (let i = 0; i < byteString.length; i++) {
  75.                 ia[i] = byteString.charCodeAt(i);
  76.             }
  77.             return new Blob([ab], { type: mimeString });
  78.         }

  79.         window.addEventListener('online', uploadPhotos);
  80.     </script>
  81. </body>
  82. </html>
复制代码

评分

参与人数 1金币 +5 收起 理由
Lay.Li + 5 赞一个!

查看全部评分

回复 使用道具 举报
Nathan.guo活字格认证 Wyn认证
超级版主   /  发表于:2024-5-23 09:29:41
2#
大佬可以先参考这篇帖子,实现离线填报功能~~

如何在Web应用中实现离线填报功能
https://gcdn.grapecity.com.cn/showtopic-167507-1-1.html
(出处: 葡萄城开发者社区)
回复 使用道具 举报
Bruce86
注册会员   /  发表于:2024-5-23 09:38:08
3#
Nathan.guo 发表于 2024-5-23 09:29
大佬可以先参考这篇帖子,实现离线填报功能~~

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

这部分已经实现了。现在是图片的存储无法实现。
回复 使用道具 举报
Nathan.guo活字格认证 Wyn认证
超级版主   /  发表于:2024-5-23 11:16:35
4#
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
5#
Nathan.guo 发表于 2024-5-23 11:16
大佬,首先,我们离线填报想实现上传图片的话,是需要先将图片转为Base64进行存储的

其次根据咱们的场 ...

感谢郭工的支持,我先试试看是否可行。
回复 使用道具 举报
Nathan.guo活字格认证 Wyn认证
超级版主   /  发表于:2024-5-23 16:52:40
7#
回复 使用道具 举报
Bruce86
注册会员   /  发表于:2024-5-23 17:01:05
8#
杜清松-808916 发表于 2024-5-23 16:22
1.文件选择与本地暂存:用户选择照片后,将照片暂存到 IndexedDB。
2.检测网络状态:利用 navigator.onLin ...

请教一下大佬 ,这个怎么绑定到 活字格的按钮中去。
回复 使用道具 举报
Nathan.guo活字格认证 Wyn认证
超级版主   /  发表于:2024-5-23 18:28:56
9#
大佬,我理解咱们把对应的JavaScript代码写好,再按钮命令中调用就好了呀~~

https://www.grapecity.com.cn/sol ... d/javascriptcommand
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部