我在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建议......