花了半天时间, 开发出了wordpress版的pwa应用。 没有借助其它组件, 比如没有使用wp service work插件。全靠纯手工,
实现pwa的步骤:
- 注册 Service Worker:在 JavaScript 文件中编写一个 Service Worker 的注册脚本,以便在页面加载时进行注册。例如:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
console.log('Service worker registered with scope: ', registration.scope);
}, function(err) {
console.log('Service worker registration failed: ', err);
});
});
}
2. 编写 Service Worker 脚本:在 sw.js 文件中编写 Service Worker 的逻辑和功能代码,包括缓存资源、拦截网络请求、离线访问等功能。例如:
Copy Code
'use strict';
const currentCache ='s_cache_0910v1';
const CACHE_FILES = [
"https://www.8kmm.com/img/8kmm.css",
"https://www.8kmm.com/img/8kmm.js",
"https://www.8kmm.com/img/logo_315_80_w.png",
"https://www.8kmm.com/img/logo_315_80.png",
"https://www.8kmm.com/img/logo_200.png",
"https://www.8kmm.com/wp-content/themes/onenav/css/style.min.css",
"https://www.8kmm.com/wp-content/themes/onenav/js/lazyload.min.js",
"https://www.8kmm.com/wp-content/themes/onenav/js/theia-sticky-sidebar.js",
"https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/fancybox/3.5.7/jquery.fancybox.min.js",
"https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/fancybox/3.5.7/jquery.fancybox.min.css",
"https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-ms/bootstrap/4.6.1/js/bootstrap.min.js",
"https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-ms/bootstrap/4.6.1/css/bootstrap.min.css",
"https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/7.4.1/swiper-bundle.min.css",
"https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.5.1/jquery.min.js",
"https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jqueryui/1.12.1/jquery-ui.min.js",
"https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js",
"https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/7.4.1/swiper-bundle.min.js",
"https://cdn.staticfile.org/popper.js/1.16.0/umd/popper.min.js",
"https://www.8kmm.com/wp-content/themes/onenav/images/bg2.svg",
"https://www.8kmm.com/wp-content/themes/onenav/images/b.cur",
"https://www.8kmm.com/wp-content/themes/onenav/images/a.cur",
"https://www.8kmm.com/wp-content/themes/onenav/css/fonts/iconfont.woff2",
"https://at.alicdn.com/t/font_2102415_t3lkts5zst.woff2",
'https://www.8kmm.com/wp-content/themes/onenav/css/iconfont.css',
'https://at.alicdn.com/t/font_2102415_t3lkts5zst.css',
"https://www.8kmm.com/wp-content/themes/onenav/js/html5.min.js",
"https://www.8kmm.com/wp-content/themes/onenav/js/app.min.js",
"https://www.8kmm.com/wp-includes/js/wp-embed.min.js",
"https://www.8kmm.com/img/r12.jpg",
"https://www.8kmm.com/img/r2.jpg",
"https://www.8kmm.com/img/r3.jpg",
"https://www.8kmm.com/img/r1.jpg",
"https://www.8kmm.com/img/r4.jpg",
"https://www.8kmm.com/img/r7.jpg",
"https://www.8kmm.com/img/r8.jpg",
"https://i.8kmm.com/2022/04/808.png",
"https://i.8kmm.com/2021/04/475eb-e40c5-6f662-6aff0-49ec4-6293f-33930-3f31b-322aa-3d2a2-9e15a-5fda4-c209a-d20d4-cefd7-QQ%E6%88%AA%E5%9B%BE20210217214526.png",
"https://i.8kmm.com/2021/04/beace-e6e3f-79c56-db1d9-b7cb8-73c5a-826cb-edda7-9fe51-73fcd-b556b-6248f-5eddc-28ddd-94522-88_911_6d6ed16888d04b62dc93951aee3e754a_641fff0c51fcce8f88eb2d8f75568c33.png",
"https://i.8kmm.com/2020/09/cropped-favicon-32x32.png",
"https://i.8kmm.com/2020/09/cropped-favicon-192x192.png",
"https://i.8kmm.com/2020/09/cropped-favicon-180x180.png",
"https://i.8kmm.com/2020/09/cropped-favicon-270x270.png",
"https://www.8kmm.com/img/logo_315_80_2.png",
"https://www.8kmm.com/wp-content/uploads/avatars/2.jpg?_=1640833906",
"https://www.8kmm.com/wp-content/themes/onenav/images/favicon.png",
"https://i.8kmm.com/2021/03/20200616174016.png",
'https://img.alicdn.com/tps/i3/T1OjaVFl4dXXa.JOZB-114-114.png',
'https://www.8kmm.com/2020/logo/20200921092954.png',
'https://i.8kmm.com/2022/01/maxthon_pic.jpg',
'https://www.8kmm.com/2020/logo/20200923141056.png',
'https://i.8kmm.com/2021/12/2Q__.jpg',
'https://www.8kmm.com/2020/logo/20200918215609.png',
'https://www.8kmm.com/2020/logo/20200918213938.png',
'https://i.8kmm.com/2021/11/www.91cha.jpg',
'https://i.8kmm.com/2021/03/20200921105914.png',
'https://www.8kmm.com/2020/logo/wxlogo.jpg',
'https://i.8kmm.com/2021/03/tt0.top-QQ%E5%9B%BE%E7%89%8720210323213527.png',
'https://www.8kmm.com/2020/logo/20200921092732.png',
'https://www.8kmm.com/2020/logo/20200921110336.png',
'https://i.8kmm.com/2022/01/20200616174757.png',
'https://i.8kmm.com/2021/05/20210519072205_102ac2843906.png',
'https://www.8kmm.com/2020/logo/20200921110416.png',
'https://www.8kmm.com/2020/logo/20200921104849.png',
'https://www.8kmm.com/2020/logo/20200925161108.png',
'https://www.8kmm.com/2020/logo/20200921092813.png',
'https://www.8kmm.com/2020/logo/20200922150608.png',
'https://www.8kmm.com/2020/logo/20200922150453.png',
'https://www.8kmm.com/2020/logo/20200921093640.png',
'https://www.8kmm.com/2020/logo/20200918203121.png',
'https://www.8kmm.com/2020/logo/20200922145319.png',
'https://www.8kmm.com/2020/logo/20200918204421.png',
'https://www.8kmm.com/2020/logo/20200918221117.png',
'https://www.8kmm.com/2020/logo/20200918220103.png',
'https://www.8kmm.com/2020/logo/20200922170039.png',
'https://i.8kmm.com/2021/03/logo.png',
'https://www.8kmm.com/2020/logo/lolsodu.png',
'https://i.8kmm.com/inter-v7-latin-500.woff2',
'https://i.8kmm.com/inter-v7-latin-700.woff2',
'https://i.8kmm.com/inter-v7-latin-600.woff2',
'https://at.alicdn.com/t/c/font_3738566_6w51ry967on.woff',
'https://i.8kmm.com/inter-v7-latin-regular.woff2'
];
self.addEventListener('install', e => {
self.skipWaiting();
e.waitUntil(
caches.open(currentCache)
.then(cache => {
const cachePromises = CACHE_FILES.map(url => {
const request = new Request(url);
return fetch(request)
.then(response => {
if (response.status === 200) {
const clonedResponse = response.clone();
const headers = new Headers(response.headers);
const now = new Date();
const expiresDate = new Date(now.getTime() + 2 * 3600 * 1000); // 设置为 2 小时过期
headers.set('Expires', expiresDate.toGMTString());
return cache.put(request, new Response(clonedResponse.body, { status: response.status, headers }));
} else {
throw new Error(`Failed to get ${url} (${response.status})`);
}
})
.catch(err => console.error(err));
});
return Promise.all(cachePromises);
})
);
});
self.addEventListener('activate', e => {
e.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== currentCache) {
return caches.delete(cacheName);
}
})
);
})
);
});
self.addEventListener('fetch', event => {
const request = event.request;
// 处理 /user/index 的请求
if (request.url.includes('/user/')||request.url.includes('/wp-admin/')) {
return event.respondWith(fetch(request)); // 直接返回请求结果,不进行缓存
}
// 检查请求是否为 bookmark 页面
if (request.url.includes('/bookmark/')) {
const url = new URL(request.url);
// 检查 URL 是否包含查询参数
if (url.search) {
// 编码查询参数后再进行 fetch
const encodedUrl = url.origin + url.pathname + encodeURI(url.search);
return event.respondWith(fetchWithRedirects(encodedUrl));
}
}
//如果访问了下面的页面,则清空缓存
if (event.request.url.includes('/wp-login.php') || event.request.url.includes('/wp-login.php?action=logout')|| event.request.url.includes('/login/')|| event.request.url.includes('/wp-admin/')|| event.request.url.includes('/user/')) {
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
return caches.delete(cacheName);
})
);
}).then(function() {
return self.clients.matchAll();
}).then(function(clients) {
clients.forEach(function(client) {
client.navigate(client.url);
});
})
);
}
// 其他处理逻辑不变
// 检查请求方法是否为 GET
if (request.method === 'GET') {
event.respondWith(
caches.match(request)
.then(response => {
if (response) {
return response;
}
return fetch(request)
.then(response => {
// 如果请求成功,则缓存响应结果
if (response && response.status === 200) {
const clonedResponse = response.clone();
caches.open(currentCache).then(cache => {
cache.put(request, clonedResponse);
});
}
return response;
})
.catch(() => {
return caches.match('/offline.html');
});
})
);}
});
async function fetchWithRedirects(requestUrl) {
let response;
let redirects = [];
do {
response = await fetch(requestUrl, { redirect: 'manual' });
if (response.status === 301 || response.status === 302) {
// 获取重定向目标 URL 并记录
const redirectUrl = new URL(response.headers.get('location'), requestUrl);
redirects.push(redirectUrl.href);
// 更新 requestUrl
requestUrl = redirectUrl.href;
}
} while (response.status === 301 || response.status === 302);
// 响应是否为重定向,如果是则应用重定向
if (redirects.length > 0) {
caches.open(currentCache).then(cache => {
cache.put(requestUrl, response.clone());
});
return Response.redirect(redirects[redirects.length - 1], 302);
}
// 响应不是重定向,则正常处理
const cache = await caches.open(currentCache);
cache.put(requestUrl, response.clone());
return response;
};
3. 编写 Web App Manifest:在 HTML 文件中添加 Web App Manifest 的 meta 标签,包括应用名称、图标、启动页面等信息。例如:
Copy Code
<link rel="manifest" href="/manifest.json">
4. 编写 Web App Manifest 文件:在 manifest.json 文件中编写 Web App Manifest 的具体信息,例如:
Copy Code
{
"name": "My PWA",
"short_name": "MyPWA",
"start_url": "/index.html",
"display": "standalone",
"icons": [
{
"src": "images/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "images/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "images/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "images/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "images/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "images/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/icon-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "images/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#3367D6",
"background_color": "#3367D6"
}
遗留问题, fetch下面的判断, 存在优化空间。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...