重新整理service-worker,让离线也可以用

This commit is contained in:
枫谷剑仙 2024-04-26 05:00:43 +08:00
parent 94d79da035
commit 426f990326
3 changed files with 128 additions and 100 deletions

View File

@ -9,7 +9,7 @@ const GM_xmlhttpRequest = function(GM_param) {
const _xhr = e.target; const _xhr = e.target;
if (_xhr.readyState === _xhr.DONE) { //请求完成时 if (_xhr.readyState === _xhr.DONE) { //请求完成时
console.debug("http状态码", _xhr.status); console.debug("http状态码", _xhr.status);
if ((_xhr.status === 200 || _xhr.status === 0) && GM_param.onload) //正确加载时 if ((_xhr.status === 200) && GM_param.onload) //正确加载时
{ {
GM_param.onload(_xhr); GM_param.onload(_xhr);
} else if (_xhr.status !== 200 && GM_param.onerror) //发生错误时 } else if (_xhr.status !== 200 && GM_param.onerror) //发生错误时

View File

@ -2045,6 +2045,7 @@ function loadData(force = false)
//开始读取解析怪物数据 //开始读取解析怪物数据
const sourceDataFolder = "monsters-info"; const sourceDataFolder = "monsters-info";
dealCkeyData();
statusLine?.writeText(localTranslating.status_message.loading_check_version); statusLine?.writeText(localTranslating.status_message.loading_check_version);
GM_xmlhttpRequest({ GM_xmlhttpRequest({
@ -2061,22 +2062,34 @@ function loadData(force = false)
//处理返回的数据 //处理返回的数据
function dealCkeyData(responseText) function dealCkeyData(responseText)
{ //处理数据版本 { //处理数据版本
const lastKeyString = localStorage.getItem(cfgPrefix + "ckey");
let newCkeys; //当前的Ckey们 let newCkeys; //当前的Ckey们
let lastCkeys; //以前Ckey们 let lastCkeys; //以前Ckey们
let currentCkey; //获取当前语言的ckey let currentCkey; //获取当前语言的ckey
let lastCurrentCkey; //以前的当前语言的ckey let lastCurrentCkey; //以前的当前语言的ckey
try { if (responseText === undefined) {
newCkeys = JSON.parse(responseText); try {
} catch (e) { newCkeys = JSON.parse(lastKeyString);
console.error("新的 Ckey 数据 JSON 解码出错。", e); console.info("提前预载原来已经储存的数据");
return; } catch (e) {
console.error("以前还没有下载过数据。", e);
return;
}
} else {
try {
newCkeys = JSON.parse(responseText);
} catch (e) {
console.error("新的 Ckey 数据 JSON 解码出错。", e);
return;
}
} }
console.debug("目前使用的数据区服是 %s。", currentDataSource.code); console.debug("目前使用的数据区服是 %s。", currentDataSource.code);
currentCkey = newCkeys.find(ckey => ckey.code == currentDataSource.code); //获取当前语言的ckey currentCkey = newCkeys.find(ckey => ckey.code == currentDataSource.code); //获取当前语言的ckey
try { try {
lastCkeys = JSON.parse(localStorage.getItem(cfgPrefix + "ckey")); //读取本地储存的原来的ckey lastCkeys = JSON.parse(lastKeyString); //读取本地储存的原来的ckey
if (!Boolean(lastCkeys) || !Array.isArray(lastCkeys)) if (!Boolean(lastCkeys) || !Array.isArray(lastCkeys))
lastCkeys = []; lastCkeys = [];
} catch (e) { } catch (e) {

View File

@ -1,5 +1,5 @@
"use strict"; "use strict";
const cacheName = 'PDDF-v1' const cacheName = 'PDDF-v1'
const cachesMap = new Map([ const cachesMap = new Map([
[ [
"images/cards_ja/CARDS_001.PNG", "images/cards_ja/CARDS_001.PNG",
@ -25519,11 +25519,11 @@ const cachesMap = new Map([
], ],
[ [
"script-universal_function.js", "script-universal_function.js",
"7d4cc7769b061422c6f55b392f3fd445" "4c6512cc2876102856ecf24775673805"
], ],
[ [
"script.js", "script.js",
"bf5e60b56a64419c5592a5c641258d3f" "3e1b60d425c9148f70ea81d518c217fd"
], ],
[ [
"solo.html", "solo.html",
@ -25753,6 +25753,10 @@ const cachesMap = new Map([
"library/html2canvas.min.js", "library/html2canvas.min.js",
"d7530aa0b7587e627484c49fdf8f13f2" "d7530aa0b7587e627484c49fdf8f13f2"
], ],
[
"library/minified.js",
"4d02ac7bb781ce3f52a8008f2047e77e"
],
[ [
"library/zxing.umd.min.js", "library/zxing.umd.min.js",
"46934f662940b020aee6466c1e334c5f" "46934f662940b020aee6466c1e334c5f"
@ -26185,93 +26189,104 @@ const cachesMap = new Map([
"doc/images/tips-voice.png", "doc/images/tips-voice.png",
"c9ee2d1ee636f63c4514dc56bc05c9fa" "c9ee2d1ee636f63c4514dc56bc05c9fa"
] ]
]); ]);
// 安装阶段跳过等待,直接进入 active // 安装阶段跳过等待,直接进入 active
self.addEventListener('install', function (event) { self.addEventListener('install', function (event) {
event.waitUntil(self.skipWaiting()); event.waitUntil(self.skipWaiting());
}); });
self.addEventListener('activate', function(event) { self.addEventListener('activate', function(event) {
console.debug("Service Worker activate"); console.debug("Service Worker activate");
const baseUrl = new URL(".", location); const baseUrl = new URL(".", location);
const baseUrlString = baseUrl.origin + baseUrl.pathname; const baseUrlString = baseUrl.origin + baseUrl.pathname;
event.waitUntil( event.waitUntil(
Promise.all([ Promise.all([
self.clients.claim(), self.clients.claim(),
caches.keys().then(function(keyList) { //所有的现存的缓存大分类列表 caches.keys().then(function(keyList) { //所有的现存的缓存大分类列表
return Promise.all( return Promise.all(
keyList.map(async function(key) { keyList.map(async function(key) {
if (cacheName !== key) { //如果不在当前的缓存列表里就删除 if (cacheName !== key) { //如果不在当前的缓存列表里就删除
console.debug("未检测到该缓存分类,删除", key); console.debug("未检测到该缓存分类,删除", key);
return caches.delete(key); return caches.delete(key);
} else { } else {
const cache = await caches.open(key); const cache = await caches.open(key);
const requests = await cache.keys(); const requests = await cache.keys();
console.debug("检测已有缓存分类", key); console.debug("检测已有缓存分类", key);
return Promise.all( return Promise.all(
requests.map(async function(request) { requests.map(async function(request) {
const url = new URL(request.url); const url = new URL(request.url);
const relativePath = (url.origin + url.pathname).replace(baseUrlString, ""); const relativePath = (url.origin + url.pathname).replace(baseUrlString, "");
const oldmd5 = url.searchParams.get("md5"); //老的md5值 const oldmd5 = url.searchParams.get("md5"); //老的md5值
const md5 = cachesMap.get(relativePath); //新的md5值 const md5 = cachesMap.get(relativePath); //新的md5值
//console.debug("检测缓存条目", url, relativePath, oldmd5, md5); //console.debug("检测缓存条目", url, relativePath, oldmd5, md5);
if (md5 && md5 !== oldmd5) { if (md5 && md5 !== oldmd5) {
console.debug("删除版本不匹配的缓存", request); console.debug("删除版本不匹配的缓存", request);
return cache.delete(request); return cache.delete(request);
} }
}) })
); );
} }
}) })
); );
}) })
]) ])
); );
}); });
self.addEventListener('fetch', async function(event) { self.addEventListener('fetch', async function(event) {
const url = new URL(event.request.url); const url = new URL(event.request.url);
url.search = ""; url.search = "";
const baseUrl = new URL(".", location); const baseUrl = new URL(".", location);
const baseUrlString = baseUrl.origin + baseUrl.pathname; const baseUrlString = baseUrl.origin + baseUrl.pathname;
const relativePath = (url.origin + url.pathname).replace(baseUrlString, ""); const relativePath = (url.origin + url.pathname).replace(baseUrlString, "");
const md5 = cachesMap.get(relativePath); //事先记录的md5值 const md5 = cachesMap.get(relativePath); //事先记录的md5值
//console.debug("请求网络", event.request.url, relativePath, md5); //console.debug("请求网络", event.request.url, relativePath, md5);
if (md5) { if (md5) {
url.searchParams.set("md5", md5); url.searchParams.set("md5", md5);
const responseWithMd5 = await caches.match(url, {ignoreSearch: false});
if (responseWithMd5) { const responseSync = (async () => {
console.debug("%c已有相同 md5 缓存,直接使用缓存:%s%s", "color: green;", relativePath, md5); // Try to get the response from a cache.
event.respondWith(responseWithMd5); const responseWithMd5 = await caches.match(url, {ignoreSearch: false});
} else { // Return it if we found one.
//console.debug("%c无相同 md5 缓存,重新在线获取", "color: blue;", url); if (responseWithMd5) {
let newResponse; console.debug("%c已有相同 md5 缓存,直接使用缓存:%s%s", "color: green;", relativePath, md5);
try { return responseWithMd5;
newResponse = await fetch(event.request); }
console.debug("%c无相同 md5 缓存,重新在线获取结果:%s%s", "color: blue;", relativePath, md5); // If we didn't find a match in the cache, use the network.
const cache = await caches.open(cacheName); try {
await cache.put(url, newResponse.clone()); const newResponse = fetch(event.request);
//console.debug("%c储存新的Cache", "color: blue;", url, cache); console.debug("%c无相同 md5 缓存,重新在线获取结果:%s%s", "color: lightblue;", relativePath, md5);
} catch (error) { const response = await newResponse;
console.error("%c数据在线获取失败尝试使用忽略 search 的离线数据:%s%s", "color: red;", relativePath, md5, error); const cache = await caches.open(cacheName);
newResponse = await caches.match(url, {ignoreSearch: true}); await cache.put(url, response.clone());
} return response;
event.respondWith(newResponse); //console.debug("%c储存新的Cache", "color: blue;", url, cache);
} } catch (error) {
} else { console.error("%c数据在线获取失败-有hash尝试使用忽略 search 的离线数据:%s%s", "color: red;", relativePath, md5, error);
console.debug("无 md5 值,重新在线获取:%s", relativePath); const response = await caches.match(url, {ignoreSearch: true});
let newResponse; return response || new Response(new Blob(), { status: 418, statusText: "数据在线获取失败" });
try { }
newResponse = await fetch(event.request); })();
const cache = await caches.open(cacheName); event.respondWith(responseSync);
await cache.put(url, newResponse.clone()); } else {
event.respondWith(newResponse); console.debug("%c无 md5 值,重新在线获取:%s", "color: lightblue;", relativePath);
} catch (error) {
console.error("%c数据在线获取失败尝试使用忽略 search 的离线数据:%s", "color: red;", relativePath, error); const responseSync = (async () => {
newResponse = await caches.match(url, {ignoreSearch: true}); try {
} const newResponse = fetch(event.request);
event.respondWith(newResponse); const response = await newResponse;
} const cache = await caches.open(cacheName);
await cache.put(url, response.clone());
return response;
//console.debug("%c储存新的Cache", "color: blue;", url, cache);
} catch (error) {
console.error("%c数据在线获取失败-无hash尝试使用忽略 search 的离线数据:%s", "color: red;", relativePath, error);
const response = await caches.match(url, {ignoreSearch: true});
return response || new Response(new Blob(), { status: 418, statusText: "数据在线获取失败" });
}
})();
event.respondWith(responseSync);
}
}); });