【问题标题】:Uploading indexedDB data to PHP in a loop循环上传 indexedDB 数据到 PHP
【发布时间】:2013-07-30 00:33:08
【问题描述】:

我正在尝试使用 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"); };

【问题讨论】:

    标签: php javascript json indexeddb


    【解决方案1】:

    如果您检查控制台是否有错误,您可能会看到:

    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。
    猜你喜欢
    • 2022-12-26
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 2017-07-25
    相关资源
    最近更新 更多