将PWA添加到主屏幕,在Chrome移动设备上不起作用



我最近进入了前端开发,为托管在树莓派上的nodejs服务器制作一个接口。 我听说过渐进式网络应用程序,并希望用户能够将其安装在他的手机上。 因此,这是清单和服务工作进程脚本。 清单:

{
"name": "Philips D6330",
"short_name": "Philips D6330",
"description": "A control app for the Philips D6330",
"icons": [
{
"src": "https://192.168.1.26/cdn/favicon.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "https://192.168.1.26",
"display": "fullscreen",
"orientation": "portrait",
"theme_color": "#333333",
"background_color": "#333333",
"scope": "/"
}

服务工作者:

const CACHE_NAME = 'cache';
const CACHE = [
'/',
'/cdn/offline.html',
'/cdn/style.css',
'/cdn/favicon.png',
'/cdn/linetoB.ttf',
'/cdn/linetoL.ttf',
'/cdn/neon.ttf',
'/cdn/not.png',
'/cdn/next.png',
'/cdn/pause.png',
'/cdn/play.png',
'/cdn/previous.png',
'/cdn/dots.png',
'/cdn/rfid.png'
];
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
return cache.addAll(CACHE)
})
.then(self.skipWaiting())
)
})
self.addEventListener('fetch', function(event) {
if (event.request.mode === 'navigate') {
event.respondWith(
fetch(event.request)
.catch(() => {
return caches.open(CACHE_NAME)
.then((cache) => {
return cache.match('/cdn/offline.html');
})
})
);
}
else {
event.respondWith(
fetch(event.request)
.catch(() => {
return caches.open(CACHE_NAME)
.then((cache) => {
return cache.match(event.request)
})
})
);
}
})
self.addEventListener('activate', function(event) {
event.waitUntil(
caches.keys()
.then((keyList) => {
return Promise.all(keyList.map((key) => {
if (key !== CACHE_NAME) {
console.log('[ServiceWorker] Removing old cache', key)
return caches.delete(key)
}
}))
})
.then(() => self.clients.claim())
)
})

我认为也有必要告诉您,所有这些都发生在我的本地网络上,因此我的节点服务器使用https和使用此教程制作的自签名证书:https://medium.com/@tbusser/creating-a-browser-trusted-self-signed-ssl-certificate-2709ce43fd15 但即使它是一个自签名证书,服务工作者似乎在 Firefox 和 chrome 上注册得很好,因为它存储文件并在离线时显示离线页面。

这是我的问题:当我想从桌面版的 chrome 安装它时,我可以但不能 chrome 手机(或三星互联网(...... 这是我用来使其可安装的代码段:

<script  defer>
window.addEventListener('beforeinstallprompt', (event) => {
console.log('👍', 'beforeinstallprompt', event);
// Stash the event so it can be triggered later.
window.deferredPrompt = event;
});
butInstall.addEventListener('click', () => {
console.log('👍', 'butInstall-clicked');
const promptEvent = window.deferredPrompt;
if (!promptEvent) {
// The deferred prompt isn't available.
return;
}
// Show the install prompt.
promptEvent.prompt();
// Log the result
promptEvent.userChoice.then((result) => {
console.log('👍', 'userChoice', result);
// Reset the deferred prompt variable, since
// prompt() can only be called once.
window.deferredPrompt = null;
});
});
window.addEventListener('appinstalled', (event) => {
console.log('👍', 'appinstalled', event);
});
</script>

它来自这里 https://web.dev/codelab-make-installable/

以下是安装前提示事件的屏幕截图,其中包含灯塔报告(顺便说一下,url 中的加号显示它正在工作(: 控制台日志信息

但是在移动设备上,加号没有显示,当我单击按钮时没有任何反应......而且由于我没有访问控制台的权限,因此看不到任何错误...

------编辑------

使用警报记录控制台所说的内容后,我认为问题来自服务工作者确实注册良好,因为我得到这个: "服务工作进程注册失败:安全错误:无法使用脚本 ('https://192.168.1.26/sw.js'( 为作用域 ('https://192.168.1.26/'( 注册服务工作进程:获取脚本时发生 SSL 证书错误。

有没有办法让浏览器信任我的自唱证书?

欢迎任何帮助、建议或意见^^

这是一个.webmanifest,你不符合条件。您需要一个 512x512 和一个 192x192 图标。

start_url我只会使用/?source=pwa

"icons": [
{
"src": "icon.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "big_icon.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": "/?source=pwa",

之后,您需要将 Web 清单与<link>

<link rel="manifest" href="/manifest.webmanifest">

检查路径是否正确。

这是我自己的小"库"来抽象事物:https://github.com/ilijanovic/serviceHelper(它正在开发中(

如果您满足所有条件,则可以使应用可安装状态

这是它如何与我的图书馆一起工作。实例化类并将路径传递给服务辅助角色。

var sh = new ServiceHelper("./sw.js");
sh.init().then(response => {
console.log("Initialized");
})
sh.on("notinstalled", (e) => {
console.log("App is not installed");
//do some stuff. For example enable some button
//button.classList.remove("disabled");
})
butInstall.addEventListener('click', () => {
sh.installApp().then(e => {
// e = user choice event
console.log(e);
}).catch(err => {
// error if the app is already installed
console.log(err);
})

最新更新