9.1 离线存储图片
本帖最后由 Bruce86 于 2024-5-23 08:40 编辑我做了一个移动端的 填报页面;由于使用人员,现场拍照使用时, 国外的网络不稳定,上传图片经常丢失等问题发生。 我想设计一个功能:用户点击“暂存”时,存储到 移动端本地数据库中; 有稳定网络的情况后,在点击“提交”,数据上传到到国内的服务器上。
界面:
遇到的问题:图片 在不联网的情况下,根本就无法保存到本地。一篇空白。而且 使用的 localstorage 本地存储 空间太小了,只有5mb,根本就放不下几张照片。
需求:想 改成 indexedDB的方式用来存储 图片数据。
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> 大佬可以先参考这篇帖子,实现离线填报功能~~
如何在Web应用中实现离线填报功能
https://gcdn.grapecity.com.cn/showtopic-167507-1-1.html
(出处: 葡萄城开发者社区)
Nathan.guo 发表于 2024-5-23 09:29
大佬可以先参考这篇帖子,实现离线填报功能~~
如何在Web应用中实现离线填报功能
这部分已经实现了。现在是图片的存储无法实现。 Bruce86 发表于 2024-5-23 09:38
这部分已经实现了。现在是图片的存储无法实现。
大佬,首先,我们离线填报想实现上传图片的话,是需要先将图片转为Base64进行存储的
其次根据咱们的场景,如果是移动端拍照,并且图片数量较多的话,建议使用HAC,因为再HAC中缓存的话,会存储的realm数据库
一看就会,超有用活字格技能:一百九十五、如何在HAC上实现离线/拍照/水印/GPS/NFC..
https://gcdn.grapecity.com.cn/showtopic-203094-1-1.html
(出处: 葡萄城开发者社区)
Nathan.guo 发表于 2024-5-23 11:16
大佬,首先,我们离线填报想实现上传图片的话,是需要先将图片转为Base64进行存储的
其次根据咱们的场 ...
感谢郭工的支持,我先试试看是否可行。 :hjyzw: 杜清松-808916 发表于 2024-5-23 16:22
1.文件选择与本地暂存:用户选择照片后,将照片暂存到 IndexedDB。
2.检测网络状态:利用 navigator.onLin ...
请教一下大佬 ,这个怎么绑定到 活字格的按钮中去。 大佬,我理解咱们把对应的JavaScript代码写好,再按钮命令中调用就好了呀~~
https://www.grapecity.com.cn/solutions/huozige/help/docs/command/javascriptcommand
页:
[1]