在 Android 和 iOS 上以独立模式在 node.js 运行 中部署了 PWA
PWA deployed in node.js running in Standalone mode on Android and iOS
我正在尝试在 Android 和 iOS 上以独立模式实施 PWA。
我有一个安全的 node.js 服务器 (HTTPS),显然一切正常(index.html、manifest.json、serviceWorker.js、...)。
应用程序 运行 正确地来自 Chrome 并且可以添加到主屏幕和 运行 在 PC 上的独立模式下。它也可以在 iOS (Safari) 上以独立模式运行,但不能在 Android (Chrome) 上运行。
因此,我测试了三种不同的 PWA:使用 ionicPWA 的基本示例,angularPWA 的另一个示例,然后使用自己的 PWA。行为是相同的,如果我在像 Firebase 这样的服务器上部署应用程序,那么应用程序在 iOS 和 Android 上都以独立模式运行。但是,如果我在我的 node.js 服务器上部署应用程序,该应用程序只能在 iOS 上以独立模式运行,但不能在 Android.
上运行
我已经在不同的 Android 设备上使用 Chrome 的 v67.0.3396.87、Android 8.1.0、7.0.0 和 6.0.0 进行了测试。 PWA 仅在浏览器模式下打开。
我看到了有关此行为的其他问题和答案 (, , ),但我还没有找到解决方案。
这可能是 Chrome-v67 的错误吗?还是我服务器的某些配置会影响 Android 上 Chrome 的行为?
有什么想法吗?
UPDATE1: index.html, manifest.json, seviceWorker (sw.js) 和审计 Chrome devTools
index.html(头)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--title-->
<title>PWA Test</title>
<!--icon-->
<link rel="shortcut icon" type="image/png" href="img/favicon.png"></link>
<!--color-->
<meta name="theme-color" content="#FB314E">
<!--for mobile-->
<meta name="MobileOptimized" content="width">
<meta name="HandheldFriendly" content="true">
<!--for Apple devices-->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" href="img/favicon.png"></link>
<link rel="apple-touch-startup-image" href="img/favicon.png"></link>
<!-- pwa configuration-->
<link rel="manifest" href="manifest.json"></link>
<!--style-->
<link rel="stylesheet" href="css/styles.css"></link>
<!--jQuery-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--Scripts-->
<script src="main.js"></script>
</head>
manifest.json
{
"name": "PWA 3002 Test",
"short_name": "PWA 3002",
"description": "PWA aplication",
"background_color": "#FFF",
"theme_color": "#FB314E",
"orientation": "portrait",
"display": "standalone",
"start_url": "./index.html?utm_source=web_app_manifest",
"scope": "./",
"lang": "es-ES",
"icons": [
{
"src": "./img/favicon-1024.png",
"sizes": "1024x1024",
"type": "image/png"
},
{
"src": "./img/favicon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "./img/favicon-384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "./img/favicon-256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "./img/favicon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "./img/favicon-128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "./img/favicon-96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "./img/favicon-32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "./img/favicon-16.png",
"sizes": "16x16",
"type": "image/png"
}
]
}
sw.js(服务人员)
// name and version of cache
const CACHE_NAME = 'v1_cache_pwa';
// for cache
var urlsToCache = [
'./',
'./css/styles.css',
'./img/favicon.png',
'./img/1.png',
'./img/2.png',
'./img/3.png',
'./img/4.png',
'./img/5.png',
'./img/6.png',
'./img/favicon-1024.png',
'./img/favicon-512.png',
'./img/favicon-384.png',
'./img/favicon-256.png',
'./img/favicon-192.png',
'./img/favicon-128.png',
'./img/favicon-96.png',
'./img/favicon-64.png',
'./img/favicon-32.png',
'./img/favicon-16.png'
];
// install event
self.addEventListener('install', e => {
e.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
return cache.addAll(urlsToCache)
.then(() =>{
self.skipWaiting();
});
})
.catch(err => {
console.log('No se ha registrado el cache', err);
})
);
});
// activate event
self.addEventListener('activate', e => {
const cacheWhiteList = [CACHE_NAME];
e.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if(cacheWhiteList.indexOf(cacheName) === -1){
// Borrar elementos que no se necesitan
return caches.delete(cacheName);
}
})
);
})
.then(() => {
//Activar cache
self.clients.claim();
})
);
});
// fetch event
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
});
Chrome DevTools 审核(在 PC 上)
测试三个应用程序(ionicPWA 示例、angularPWA 示例、我自己的 PWA):
使用 ionicPWA 控制台中出现两个警告:
*vendor.js:1:本机:尝试调用 StatusBar.styleDefault,但 Cordova 不可用。确保在 device/simulator 中包含 cordova.js 或 运行
E
*DevTools 无法解析 SourceMap:https://xxx.xxx.xxx/build/sw-toolbox.js.map
(index):28 service worker 安装
使用 AngularPWA 没有 messages/errors/warnings 出现...
我自己的 PWA 应用程序,同样的行为..没有 messages/errors/warnings 出现在 PC Chrome devTools 的控制台中
我已经解决了问题。一位同事告诉我,问题可能是由于服务器上配置的端口引起的。
我已将服务器 node.js 配置为侦听特定端口 (https://mydomain:xxxx),而不是默认端口 (443),这由于某种原因导致 PWA 应用程序无法在 [=14] 上以独立模式工作=].
我在默认端口“443”中设置了服务器,并且 PWA 应用程序已经在 Android 和 iOS 的独立模式下正常工作。
感谢大家。
我正在尝试在 Android 和 iOS 上以独立模式实施 PWA。 我有一个安全的 node.js 服务器 (HTTPS),显然一切正常(index.html、manifest.json、serviceWorker.js、...)。
应用程序 运行 正确地来自 Chrome 并且可以添加到主屏幕和 运行 在 PC 上的独立模式下。它也可以在 iOS (Safari) 上以独立模式运行,但不能在 Android (Chrome) 上运行。
因此,我测试了三种不同的 PWA:使用 ionicPWA 的基本示例,angularPWA 的另一个示例,然后使用自己的 PWA。行为是相同的,如果我在像 Firebase 这样的服务器上部署应用程序,那么应用程序在 iOS 和 Android 上都以独立模式运行。但是,如果我在我的 node.js 服务器上部署应用程序,该应用程序只能在 iOS 上以独立模式运行,但不能在 Android.
上运行我已经在不同的 Android 设备上使用 Chrome 的 v67.0.3396.87、Android 8.1.0、7.0.0 和 6.0.0 进行了测试。 PWA 仅在浏览器模式下打开。
我看到了有关此行为的其他问题和答案 (
这可能是 Chrome-v67 的错误吗?还是我服务器的某些配置会影响 Android 上 Chrome 的行为?
有什么想法吗?
UPDATE1: index.html, manifest.json, seviceWorker (sw.js) 和审计 Chrome devTools
index.html(头)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--title-->
<title>PWA Test</title>
<!--icon-->
<link rel="shortcut icon" type="image/png" href="img/favicon.png"></link>
<!--color-->
<meta name="theme-color" content="#FB314E">
<!--for mobile-->
<meta name="MobileOptimized" content="width">
<meta name="HandheldFriendly" content="true">
<!--for Apple devices-->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" href="img/favicon.png"></link>
<link rel="apple-touch-startup-image" href="img/favicon.png"></link>
<!-- pwa configuration-->
<link rel="manifest" href="manifest.json"></link>
<!--style-->
<link rel="stylesheet" href="css/styles.css"></link>
<!--jQuery-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--Scripts-->
<script src="main.js"></script>
</head>
manifest.json
{
"name": "PWA 3002 Test",
"short_name": "PWA 3002",
"description": "PWA aplication",
"background_color": "#FFF",
"theme_color": "#FB314E",
"orientation": "portrait",
"display": "standalone",
"start_url": "./index.html?utm_source=web_app_manifest",
"scope": "./",
"lang": "es-ES",
"icons": [
{
"src": "./img/favicon-1024.png",
"sizes": "1024x1024",
"type": "image/png"
},
{
"src": "./img/favicon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "./img/favicon-384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "./img/favicon-256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "./img/favicon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "./img/favicon-128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "./img/favicon-96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "./img/favicon-32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "./img/favicon-16.png",
"sizes": "16x16",
"type": "image/png"
}
]
}
sw.js(服务人员)
// name and version of cache
const CACHE_NAME = 'v1_cache_pwa';
// for cache
var urlsToCache = [
'./',
'./css/styles.css',
'./img/favicon.png',
'./img/1.png',
'./img/2.png',
'./img/3.png',
'./img/4.png',
'./img/5.png',
'./img/6.png',
'./img/favicon-1024.png',
'./img/favicon-512.png',
'./img/favicon-384.png',
'./img/favicon-256.png',
'./img/favicon-192.png',
'./img/favicon-128.png',
'./img/favicon-96.png',
'./img/favicon-64.png',
'./img/favicon-32.png',
'./img/favicon-16.png'
];
// install event
self.addEventListener('install', e => {
e.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
return cache.addAll(urlsToCache)
.then(() =>{
self.skipWaiting();
});
})
.catch(err => {
console.log('No se ha registrado el cache', err);
})
);
});
// activate event
self.addEventListener('activate', e => {
const cacheWhiteList = [CACHE_NAME];
e.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if(cacheWhiteList.indexOf(cacheName) === -1){
// Borrar elementos que no se necesitan
return caches.delete(cacheName);
}
})
);
})
.then(() => {
//Activar cache
self.clients.claim();
})
);
});
// fetch event
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
});
Chrome DevTools 审核(在 PC 上)
测试三个应用程序(ionicPWA 示例、angularPWA 示例、我自己的 PWA):
使用 ionicPWA 控制台中出现两个警告:
*vendor.js:1:本机:尝试调用 StatusBar.styleDefault,但 Cordova 不可用。确保在 device/simulator 中包含 cordova.js 或 运行 E
*DevTools 无法解析 SourceMap:https://xxx.xxx.xxx/build/sw-toolbox.js.map (index):28 service worker 安装
使用 AngularPWA 没有 messages/errors/warnings 出现...
我自己的 PWA 应用程序,同样的行为..没有 messages/errors/warnings 出现在 PC Chrome devTools 的控制台中
我已经解决了问题。一位同事告诉我,问题可能是由于服务器上配置的端口引起的。 我已将服务器 node.js 配置为侦听特定端口 (https://mydomain:xxxx),而不是默认端口 (443),这由于某种原因导致 PWA 应用程序无法在 [=14] 上以独立模式工作=]. 我在默认端口“443”中设置了服务器,并且 PWA 应用程序已经在 Android 和 iOS 的独立模式下正常工作。 感谢大家。