我的服务工作者中的IndexedDB add()成功但我无法在Chrome开发工具应用程序/存储

时间:2017-03-28 10:34:02

标签: javascript google-chrome-devtools indexeddb service-worker

我在MacOS / OSX 12.3 Sierra上使用Chrome版本57.0.2987.110(64位),

我设法让服务工作者工作,但我必须说我是新人。

我现在尝试使用IndexedDB并将数据存储在其中。

它从http中的本地Web服务器获取数据,并以json格式检索它没有问题。

数据格式为:

[{"id":"1", "...":"...", ...},
 {"id":"2", "...":"...", ...},
 {"id":"3", "...":"...", ...},
 ...
 {"id":"n", "...":"...", ...}]

然后显然将数据添加到IndexedDB而没有问题,因为触发了onsuccess回调......

entityObjectStore.add success : Event {isTrusted: true, type: "success", target: IDBRequest, currentTarget: IDBRequest, eventPhase: 2…}

但它没有出现在Chrome开发工具中!

这是我的服务人员:

self.addEventListener('install',function(event)
    {
    event.waitUntil(
        (new Promise(function(resolve,reject)resolve()}))
        .then(function()
            {return self.skipWaiting();}));
    });

self.addEventListener('activate', function(event)
    {
    event.waitUntil(
        (new Promise(function(resolve,reject){resolve()}))
        .then(function() {return self.clients.claim();}));
    });

self.addEventListener('message', function(event)
    {
    if(event.data.command=="data.load")
        {
        var options = event.data.options
        var url = new URL(event.data.host+options.source);
        var parameters = {entity:options.name,
                          options:encodeURIComponent(options.options)};
        Object.keys(parameters)
            .forEach(key => url.searchParams.append(key,
                                                    parameters[key]))
        fetch(url).then(function(response)
            {
            if(response.ok)
                {
                response.json().then(function(data_json)
                    {
                    var entityData = data_json;
                    var request = indexedDB.open(options.name);
                    request.onerror = function(event)
                        {
                        console.log("indexedDB.open error :",event);
                        };
                    request.onsuccess = function(event)
                        {
                        console.log("indexedDB.open success :",event)
                        var db = event.target.result;
                        }
                    request.onupgradeneeded = function(event)
                        {
                        console.log("indexedDB.open upgrade :",event)
                        var db = event.target.result;
                        db.createObjectStore(options.options.id, { keyPath: "id" });
                        objectStore.transaction.oncomplete = function(event)
                            {
                            var entityObjectStore = db.transaction(options.options.id, "readwrite").objectStore(options.options.id);
                            for (var i in entityData)
                                {
                                var addRequest = entityObjectStore.add(entityData[i]);
                                addRequest.onerror = function(event)
                                    {
                                    console.log("entityObjectStore.add error :",event);
                                    };
                                addRequest.onsuccess = function(event)
                                    {
                                    console.log("entityObjectStore.add success :",event);
                                    };
                                }
                            }
                        };

                    });
                }
            });
        }
    else if(event.data.command=="data.get")
        {
        var command = event.data;
        var request = indexedDB.open(command.domain);
        request.onerror = function(event)
            {
            console.log("indexedDB.open error :",event);
            };
        request.onsuccess = function(event)
            {
            console.log("indexedDB.open success :", event)
            var db = event.target.result;
            var transaction = db.transaction([command.domain]);
            var objectStore = transaction.objectStore(command.entity);
            var request = objectStore.get(command.id);
            request.onerror = function(event)
                {
                console.log("objectStore.get error :",event);
                };
            request.onsuccess = function(event)
                {
                console.log("objectStore.get success :",event);
                console.log("request.result=" + request.result);
                };          
            }
        }
    });

以下是我使用的HTML文件:

<!DOCTYPE html>
<html>
    <head>
        <title>My service worker app</title>
    </head>
    <body>
        <button id="update">Update</button>
        <div id="log"></div>
        <script type="text/javascript">
        function sendMessage(message)
            {
            return new Promise(function(resolve, reject)
                {
                var messageChannel = new MessageChannel();
                messageChannel.port1.onmessage = function(event)
                    {
                    if (event.data.error)
                        {
                        reject(event.data.error);
                        }
                    else
                        {
                        resolve(event.data);
                        }
                    };

                });
            }
            if (navigator.serviceWorker.controller)
                {
                var url = navigator.serviceWorker.controller.scriptURL;
                var initData =  [
                                {
                                name:"my_entity_type",
                                source:"/webapp/data",
                                options:{id:"my_entity_type_id"}
                                }
                                ]
                for(var dataIndex in initData)
                    {
                    var data = initData[dataIndex]
                    sendMessage({
                                 command:"data.load",
                                 host: document.location.origin,
                                 options: data
                                 });
                    }
                }
            else
                {
                navigator.serviceWorker.register('/webapp/lt_sw.js')
                    .then(function(registration)
                        {
                        debug('Refresh to allow ServiceWorker to control this client', 'onload');
                        debug(registration.scope, 'register');
                        });
                }

    navigator.serviceWorker.addEventListener('controllerchange', 
    function() 
        {
        var scriptURL = navigator.serviceWorker.controller.scriptURL;
        debug(scriptURL, 'oncontrollerchange');
        });

    document.querySelector('#update').addEventListener('click', 
    function() 
        {
        navigator.serviceWorker.ready.then(function(registration)
            {
            registration.update()
                .then(function()
                    {
                    console.log('Checked for update');
                    })
                .catch(function(error)
                    {
                    console.error('Update failed', error);
                    });
                });
            });

        function debug(message, element)
            {
            var target = document.querySelector('#log');
            console.log(element,":",message)
            target.textContent = message;
            }
        </script>
    </body>
</html>

对我的看法,做错了?

修改1:

我修改了html文件中的脚本,以便更新机制向服务工作者发送另一条消息,询问数据:

    document.querySelector('#update').addEventListener('click', 
    function() 
        {
        navigator.serviceWorker.ready.then(function(registration)
            {
            registration.update()
                .then(function()
                    {
                    console.log('Checked for update');
                    sendMessage({
                        command:"data.get",
                        domain:"database_name",
                        entity: "my_entity_type",
                        id: "my_entity_id"
                        });
                    })
                .catch(function(error)
                    {
                    console.error('Update failed', error);
                    });
                });
            });

我添加了以下内容:

    indexedDB.webkitGetDatabaseNames().onsuccess = function(sender,args){ console.log("data.get all dbs:",sender.target.result); };

刚开始查看数据部分:

    else if(event.data.command=="data.get")
        {

按照此处的说明列出Chrome上的所有IndexedDB:https://stackoverflow.com/a/15234833/2360577 我得到了我之前创建的所有数据库!

data.get all dbs: DOMStringList {0: "db1", 1: "db2", 2: "db3", 3: "db4", length: 4}

然后我继续列出这些dbs中的所有ObjectStore,也如上一个链接中所述,添加以下行:

indexedDB.open(<databaseName>).onsuccess = function(sender,args) 
{"<databaseName>'s object stores",console.log(sender.target.result.objectStoreNames); };

除了一个,处理数据并且显然不起作用的地方之外,它们都有一个对象存储,其名称与包含它的数据库名称相同...

db1's object stores DOMStringList {0: "db1", length: 1}
db2's object stores DOMStringList {length: 0}
db3's object stores DOMStringList {0: "db3", length: 1}
db4's object stores DOMStringList {0: "db4", length: 1} 

然后我看了一下对象商店......

indexedDB.open("db3").onsuccess = function(event)
{event.target.result.transaction(["db3"]).objectStore("db3")
    .getAll().onsuccess = function(event)
    {console.log("objectStore.getAll() success :",event.target.result)};};

条目符合预期!但不是在应用/存储......

编辑2:

db2 的错误显然是我没有刷新数据库中的数据......这部分现在有用......

编辑3:

答案就像关闭和重新打开开发工具一样简单......就像@wOxxOm建议......

2 个答案:

答案 0 :(得分:1)

您还可以查看&#34;重新加载更新&#34;按钮并尝试硬重置wscript,效果与@wOxxOm提到的效果相同。 enter image description here

答案 1 :(得分:1)

如果我关闭DevTools并再次打开,它对我有用。你试过吗?