Javascript pwa-提示添加到主屏幕dosen';不显示

Javascript pwa-提示添加到主屏幕dosen';不显示,javascript,symfony,service-worker,progressive-web-apps,Javascript,Symfony,Service Worker,Progressive Web Apps,我使用symfony 4.3开发了一个web应用程序,然后向其中添加了pwa功能。我使用铬合金灯塔扩展进行测试,结果如下: 现在的问题是提示将图标添加到主屏幕,但该图标未显示,我有以下错误: 未捕获的TypeError:无法读取未定义的属性“prompt” 代码js: var deferredPrompt ; var btnAdd = document.getElementById('butInstall') ; function launchPromptPwa(){ var def

我使用symfony 4.3开发了一个web应用程序,然后向其中添加了pwa功能。我使用铬合金灯塔扩展进行测试,结果如下:

现在的问题是提示将图标添加到主屏幕,但该图标未显示,我有以下错误:

未捕获的TypeError:无法读取未定义的属性“prompt”

代码js:

var deferredPrompt ;
var btnAdd = document.getElementById('butInstall') ;

function launchPromptPwa(){
    var deferredPrompt;

    btnAdd = document.getElementById('butInstall') ;

    window.addEventListener('beforeinstallprompt',  (e) => {
        console.log('0');

        // Prevent Chrome 67 and earlier from automatically showing the prompt
        e.preventDefault();
        // Stash the event so it can be triggered later.
        deferredPrompt = e;
        btnAdd.style.display = block;
        showAddToHomeScreen();
    });

    btnAdd.addEventListener('click', (e) => {
        console.log('1');
        //btnAdd.style.display = 'none';
        //Show the prompt
        deferredPrompt.prompt();
        // Wait for the user to respond to the prompt
        deferredPrompt.userChoice
            .then((choiceResult) => {
                if (choiceResult.outcome === 'accepted') {
                    console.log('User accepted the A2HS prompt');
                } else {
                    console.log('User dismissed the A2HS prompt');
                }
                deferredPrompt = null;
            });
    });


    window.addEventListener('appinstalled', (evt) => {
        console.log('a2hs installed');
    });

    if (window.matchMedia('(display-mode: standalone)').matches) {
        console.log('display-mode is standalone');
    }

}

我在chrome中测试显示提示。

为了避免错误,您可以先测试
延迟提示
变量是否已初始化,如果未定义,则跳过代码逻辑:

if (deferredPrompt) {

  deferredPrompt.prompt();

 // ... 
}
然后,是否触发
beforestinstallprompt
事件
如果是这样,当您使用
事件
对象初始化变量时,必须证明该对象是否已定义:

deferredPrompt = e;
请记住,您需要一个正在运行的
服务人员
,以便触发
beforestinstallprompt
事件。服务工作者需要安全连接(https)或运行本地主机,并通过web服务器提供服务

您可以打开Chrome开发工具(F12)并访问“应用程序”选项卡,以验证是否正确设置了web清单并安装了服务工作者

我写了一些关于你是否有兴趣深化这个话题的文章。
更新
如果您希望脱机提供内容,则必须为您的服务工作者实施缓存策略(例如,在重新验证时过时)。通过上面的链接,您可以了解不同的策略以及如何实施它们

当您实现缓存策略时,服务工作者将拦截所有静态资产(如css或js文件)或数据请求,如果与给定规则匹配,它将缓存它们或从缓存中提供它们。由于缓存位于客户端,因此这些资源也可以脱机使用

例如,要缓存静态资产:

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(cacheName).then(function(cache) {
      return cache.addAll(
        [
          '/css/bootstrap.css',
          '/css/main.css',
          '/js/bootstrap.min.js',
          '/js/jquery.min.js',
          '/offline.html'
          // Add anything else you need to be cached during the SW install
        ]
      );
    })
  );
});

为了避免错误,您可以先测试
delferredprompt
变量是否已初始化,如果未定义,则跳过代码逻辑:

if (deferredPrompt) {

  deferredPrompt.prompt();

 // ... 
}
然后,是否触发
beforestinstallprompt
事件
如果是这样,当您使用
事件
对象初始化变量时,必须证明该对象是否已定义:

deferredPrompt = e;
请记住,您需要一个正在运行的
服务人员
,以便触发
beforestinstallprompt
事件。服务工作者需要安全连接(https)或运行本地主机,并通过web服务器提供服务

您可以打开Chrome开发工具(F12)并访问“应用程序”选项卡,以验证是否正确设置了web清单并安装了服务工作者

我写了一些关于你是否有兴趣深化这个话题的文章。
更新
如果您希望脱机提供内容,则必须为您的服务工作者实施缓存策略(例如,在重新验证时过时)。通过上面的链接,您可以了解不同的策略以及如何实施它们

当您实现缓存策略时,服务工作者将拦截所有静态资产(如css或js文件)或数据请求,如果与给定规则匹配,它将缓存它们或从缓存中提供它们。由于缓存位于客户端,因此这些资源也可以脱机使用

例如,要缓存静态资产:

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(cacheName).then(function(cache) {
      return cache.addAll(
        [
          '/css/bootstrap.css',
          '/css/main.css',
          '/js/bootstrap.min.js',
          '/js/jquery.min.js',
          '/offline.html'
          // Add anything else you need to be cached during the SW install
        ]
      );
    })
  );
});

调用
deferredPrompt.prompt()
时,似乎没有设置
deferredPrompt
。但是调用deferredPrompt.prompt()时如何定义deferredPrompt!!调用
deferredPrompt.prompt()
时,似乎没有设置
deferredPrompt
。但是调用deferredPrompt.prompt()时如何定义deferredPrompt!!是否可以将所有站点设置为脱机模式?我已向服务器请求获取数据。。。如何脱机处理此请求??您必须配置要缓存的路由/端点。还可以使用全局表达式。然后,当应用程序发出GET请求(或对静态资产的请求)时,如果与其中一个配置的端点匹配,软件将缓存响应,根据您选择的策略。如果页面X在脱机模式下不可用,如何显示模式。例如,在联机模式下,我访问页面登录和主页,在脱机模式下,我访问页面注册表,而此页面不可用,则将显示错误“页面不可访问”。。它将显示模式,而不是显示错误导航器。您必须设计一个通用的脱机页面(或类似的页面,根据您的需要),以便在用户打开以前未缓存的页面时重定向所有流量。这将为您提供足够的灵活性,以涵盖像您当前这样的情况。是否可以将所有站点置于脱机模式下可见?我已向服务器请求获取数据。。。如何脱机处理此请求??您必须配置要缓存的路由/端点。还可以使用全局表达式。然后,当应用程序发出GET请求(或对静态资产的请求)时,如果与其中一个配置的端点匹配,软件将缓存响应,根据您选择的策略。如果页面X在脱机模式下不可用,如何显示模式。例如,在联机模式下,我访问页面登录和主页,在脱机模式下,我访问页面注册表,而此页面不可用,则将显示错误“页面不可访问”。。它将显示模式,而不是显示错误导航器。您必须设计一个通用的脱机页面(或类似的页面,根据您的需要),以便在用户打开以前未缓存的页面时重定向所有流量。这将为您提供足够的灵活性,以涵盖像您目前这样的案例。