Javascript 检查是 PWA 还是 MobileWeb

我很好奇是否有人知道一种基于 javascript 的方法来检测网络体验是作为一个 PWA (渐进式网络应用程序)运行,还是仅仅作为一个标准的移动网站(具有完整的浏览器用户界面)运行。

“安装”的 PWA 和没有安装但仍然注册了服务工作者和/或应用程序缓存的 PWA 之间有什么区别吗?

41967 次浏览

Progressive enhancement is more a concept than an specific function or method that involves several technologies. Now progressive web apps are base on service workers which you can verify if the browser support it.

// Check for browser support of service worker
if ('serviceWorker' in navigator)

Project lighthouse can help you to detect whether an application is progressive enhanced by performing evaluations of several technologies. Take a look on it.

enter image description here

Hope this help, to clarify.

If this is for analytical purposes you could set the start URL in the manifest file to include a query string parameter, ex:

"start_url": "./?mode=standalone"

Then in your JavaScript you are able to check for this query string parameter.


Update (2020-08-19)

Pete LePage wrote a blog on how to setup a custom dimension in Google Analytics using the code below which checks the display mode using window.matchMedia:

let displayMode = 'browser';
const mqStandAlone = '(display-mode: standalone)';
if (navigator.standalone || window.matchMedia(mqStandAlone).matches) {
displayMode = 'standalone';
}
ga('set', 'dimension1', displayMode);

Read more: https://petelepage.com/blog/2020/08/measure-understand-how-installed-pwa-users-differ-from-browser-tab-users/

Update (2017-01-20):

Alternatively you could check in JavaScript using:

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

Edit 11 Oct 2019: Added an extra switch to check if the app is launched via TWA - document.referrer.includes('android-app://')

This works for all - TWA, Chrome & Safari:

const isInStandaloneMode = () =>
(window.matchMedia('(display-mode: standalone)').matches) || (window.navigator.standalone) || document.referrer.includes('android-app://');


if (isInStandaloneMode()) {
console.log("webapp is installed")
}

In my PWA, created with Microsoft Visual Studio 2017, following statement works:

var isPWA = navigator.userAgent.match(/MSAppHost/i);
if (window.matchMedia('(display-mode: standalone)').matches) {
console.log("This is running as standalone.");
}

This answer is correct but it's worth to mention that PWA could run on plenty of display modes:

  • fullscreen
  • standalone
  • minimal-ui
  • browser

If you run your PWA in a 'fullscreen' mode it will return false so additional checks are necessary like:

function isPwa() {
return ["fullscreen", "standalone", "minimal-ui"].some(
(displayMode) => window.matchMedia('(display-mode: ' + displayMode + ')').matches
);
}

Note that window.matchMedia check will return true for the 'browser' display mode even when it's not an installed PWA app.