Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
559 views
in Technique[技术] by (71.8m points)

ionic framework - PWA deployed in node.js running in Standalone mode on Android and iOS

I am trying to implement PWA in standalone mode on Android and iOS. I have a secure node.js server (HTTPS) and everything is apparently working fine (index.html, manifest.json, serviceWorker.js, ...).

The application runs correctly from Chrome and can be added to the home screen and run in standalone mode on the PC. It also works in standalone mode on iOS (Safari), but not on Android (Chrome).

Because of this, I tested three different PWAs: with a basic example of ionicPWA, another example of angularPWA, and then with an own PWA. The behavior is the same, if I deploy applications on a server like Firebase, then the apps work in standalone mode on both iOS and Android. But if I deploy the apps on my node.js server, the application only works in standalone mode on iOS but not on Android.

I have tested on different Android devices with the v67.0.3396.87 of Chrome, on Android 8.1.0, 7.0.0 and 6.0.0. The PWA only opens in browser mode.

I have seen other questions and answers about this behavior (ref1, ref2, ref3) but I have not found the solution.

Could this be a bug of Chrome-v67? Or can it be some configuration of my server that affects the behavior of Chrome on Android?

Any ideas?

UPDATE1: index.html, manifest.json, seviceWorker (sw.js) and audit with Chrome devTools

index.html (head)

<!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 (service worker)

    // 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 audit (on PC)

Testing three apps (ionicPWA example, angularPWA example, my own PWA):

  • with ionicPWA two warngins appears in the console:

    *vendor.js:1: Native: tried calling StatusBar.styleDefault, but Cordova is not available. Make sure to include cordova.js or run in a device/simulator E

    *DevTools failed to parse SourceMap: https://xxx.xxx.xxx/build/sw-toolbox.js.map (index):28 service worker installed

  • with AngularPWA no messages/errors/warnings appears...

  • with my own PWA app, the same behavior.. no messages/errors/warnings appears in the console of Chrome devTools on PC

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have solved the problem. A colleague told me that maybe the problem was due to the port configured on the server. I had configured the server node.js listening on a specific port (https://mydomain:xxxx), not in the default port (443), and this for some reason caused the PWA application not work in standalone mode on Android. I set up the server in the default port "443" and the PWA application already works correctly in standalone mode in both Android and iOS. Thanks to all.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...