sw-3.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. let pageUpdateTime = {};
  2. const CACHE_NAME = "fed-cache";
  3. let util = {
  4. getPageName: function(url) {
  5. if (url.pathname === "/" || !url.pathname) {
  6. return "home"
  7. } else {
  8. let matches = url.pathname.match(/\/([^/] + )\/$/ );
  9. if (!matches) console.log("get page name come across url: " + url);
  10. return matches ? matches[1] : ""
  11. }
  12. },
  13. isHtmlPage: function(url) {
  14. return url.pathname === "/" || /^\/page\/\d+/.test(url.pathname) || /^\/\d{4}\/\d{2}\/\d{2}/.test(url.pathname)
  15. },
  16. updateHtmlPage: async function(url, htmlRequest) {
  17. let pageName = util.getPageName(url);
  18. let jsonRequest = new Request("/html/service-worker/cache-json/" + pageName + ".sw.json");
  19. fetch(jsonRequest).then(response => {
  20. if (response.status !== 200) {
  21. console.warn(`$ {
  22. response.status
  23. }: fetch $ {
  24. pageName
  25. }.sw.json failed`);
  26. return;
  27. }
  28. response.json().then(content => {
  29. if (pageUpdateTime[pageName] !== content.updateTime) {
  30. console.log("update page html");
  31. util.fetchPut(htmlRequest, false,
  32. function() {
  33. util.postMessage({
  34. type: 1,
  35. desc: "html found updated",
  36. url: url.href
  37. })
  38. });
  39. pageUpdateTime[pageName] = content.updateTime
  40. }
  41. })
  42. })
  43. },
  44. updateHtmlTime: function(url) {
  45. let pageName = util.getPageName(url);
  46. let jsonRequest = new Request("/html/service-worker/cache-json/" + pageName + ".sw.json");
  47. fetch(jsonRequest).then(response => {
  48. response.json().then(content => {
  49. pageUpdateTime[pageName] = content.updateTime
  50. })
  51. })
  52. },
  53. putCache: function(request, resource) {
  54. if (request.method === "GET" && request.url.indexOf("wp-admin") < 0 && request.url.indexOf("preview_id") < 0 && request.url.indexOf("test=true") < 0 && request.url.indexOf("/category/") < 0 && request.url.indexOf("/author/") < 0 && request.url.indexOf("/html/") < 0) {
  55. caches.open(CACHE_NAME).then(cache => {
  56. cache.put(request.url, resource)
  57. })
  58. }
  59. },
  60. fetchPut: function(request, putCache = true, callback) {
  61. return fetch(request).then(response => {
  62. if (!response || response.status !== 200 || response.type !== "basic") {
  63. return response
  64. }
  65. util.putCache(request, response.clone());
  66. typeof callback === "function" && callback();
  67. return response
  68. })
  69. },
  70. delCache: function(url) {
  71. caches.open(CACHE_NAME).then(cache => {
  72. console.log("delete cache " + url);
  73. cache.delete(url, {
  74. ignoreVary: true
  75. })
  76. })
  77. },
  78. postMessage: async function(msg) {
  79. const allClients = await clients.matchAll();
  80. allClients.forEach(client => client.postMessage(msg))
  81. }
  82. };
  83. const messageProcess = {
  84. 1 : function(url) {
  85. util.delCache(url)
  86. }
  87. };
  88. this.addEventListener("install", function(event) {
  89. this.skipWaiting();
  90. console.log("install service worker");
  91. caches.open(CACHE_NAME);
  92. let cacheResources = ["https://fed.renren.com/?launcher=true"];
  93. event.waitUntil(caches.open(CACHE_NAME).then(cache => {
  94. cache.addAll(cacheResources)
  95. }))
  96. });
  97. this.addEventListener("active", function(event) {
  98. clients.claims();
  99. console.log("service worker is active")
  100. });
  101. this.addEventListener("fetch", function(event) {
  102. event.respondWith(caches.match(event.request).then(response => {
  103. if (response) {
  104. if (response.headers.get("Content-Type").indexOf("text/html") >= 0) {
  105. console.log("update html");
  106. let url = new URL(event.request.url);
  107. util.updateHtmlPage(url, event.request.clone(), event.clientId)
  108. }
  109. return response
  110. }
  111. let url = new URL(event.request.url);
  112. if (util.isHtmlPage(url)) {
  113. console.log("update html time");
  114. util.updateHtmlTime(url)
  115. }
  116. let request = event.request.url.indexOf("http://fed.renren.com") >= 0 ? new Request(event.request.url.replace("http://", "https://")) : event.request.clone();
  117. return util.fetchPut(request)
  118. }))
  119. });
  120. this.addEventListener("message", function(event) {
  121. let msg = event.data;
  122. console.log(msg);
  123. if (typeof messageProcess[msg.type] === "function") {
  124. messageProcess[msg.type](msg.url)
  125. }
  126. });
  127. this.addEventListener("push", function(event) {
  128. console.log("[Service Worker] Push Received.");
  129. console.log(` [Service Worker] Push had this data: "${event.data.text()}"`);
  130. let notificationData = event.data.json();
  131. notificationData.requireInteraction = true;
  132. const title = notificationData.title;
  133. event.waitUntil(self.registration.showNotification(title, notificationData))
  134. });
  135. this.addEventListener("notificationclick", function(event) {
  136. console.log("[Service Worker] Notification click Received.");
  137. let notification = event.notification;
  138. notification.close();
  139. event.waitUntil(clients.openWindow(notification.data.url))
  140. });
  141. this.addEventListener("notificationclose", function(event) {
  142. console.log("notification close");
  143. console.log(JSON.stringify(event.notification))
  144. });