我正在尝试使用indexedDB来存储离线数据,然后在连接时上传数据。在以下代码中,使用循环从 indexedDB 读取数据,并为表(存储)中的每个记录(对象)创建一个 JSON 对象并将其发布到 PHP 文件。然而,这个indexedDB循环只执行一次。这是因为 JSON 对象是异步发送到服务器的吗?
var trans = LocalDB.indexedDB.db.transaction(storename,
IDBTransaction.READ_WRITE);
var store = trans.objectStore(storename);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
var obj = new Object;
obj.name = result.value.Name;
obj.Date = result.value.Date;
if (window.XMLHttpRequest)
xmlhttp = new XMLHttpRequest();
else
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
alert(xmlhttp.responseText);//problem: only shown once
result.continue();
}
};
xmlhttp.open("POST", "upload.php");
xmlhttp.setRequestHeader("Content-type", "application/json", true);
xmlhttp.send(JSON.stringify(obj));
};
cursorRequest.onerror = function (e) { alert("Error uploading"); };
最佳答案
如果您检查控制台是否有错误,您可能会看到:
Uncaught Error: TransactionInactiveError
这似乎是由于 Ajax 请求延迟了 result.continue()
造成的。与此同时,事务显然变得不活动并且不能再被游标使用。
您需要将 result.continue()
移出 onreadystatechange
:
// ...
xmlhttp.send(JSON.stringify(obj));
result.continue();
您还可以选择Sjax(同步)。但是,通常不建议这样做。
<小时/>另外,请注意,onsuccess
回调将被额外调用一次,并带有 null
result
来表示光标已完成,因此您想要对此进行测试:
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
if (!result) {
console.log('Done');
return; // exit callback
}
// ...
};
您还可以使用它通过单个 Ajax 请求发送 Array
中的整个集合:
var storedCollection = [];
cursorResult.onsuccess = function (e) {
var result = e.target.result;
if (result) {
storedCollection.push(result.value);
result.continue();
return; // exit callback
}
// else: the cursor is "done"
var xmlhttp = new XMLHttpRequest();
// ...
xml.send(JSON.stringify(storedCollection));
};
示例:http://jsfiddle.net/CZBrd/ (检查控制台)
关于php - 循环上传indexedDB数据到PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17937251/