Nuxt PWA 注册服务工作者未在本地主机之外注册

问题描述 投票:0回答:1

我们正在尝试托管 PWA nuxt,服务工作人员将仅使用 localhost:3000 进行注册

npm start

尝试从 192.168.0.2:3000 访问它会导致以下情况:

页面不是从安全来源提供的 没有匹配的服务工作者 检测到。您可能需要重新加载页面,或检查范围 当前页面的 Service Worker 包含范围并开始 清单中的 URL。

nuxt.config.js

    export default {
    // Global page headers: https://go.nuxtjs.dev/config-head
    head: {
        title: 'ONX',
        htmlAttrs: {
            lang: 'en'
        },
        meta: [
            { charset: 'utf-8' },
            { name: 'viewport', content: 'width=device-width, initial-scale=1' },
            { hid: 'description', name: 'description', content: '' },
            { name: 'format-detection', content: 'telephone=no' }
        ],
        link: [
            { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
        ]
    },


    // Global CSS: https://go.nuxtjs.dev/config-css
    css: [],

    // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
    plugins: [

        //{src: '~/plugins/VueCtkDateTimePicker.js', ssr: false }, // datepicker plugin here
        { src: '~/plugins/DateTimePicker.js' },
        { src: '~/plugins/VueTabulator.js', mode: 'client', ssr: false }

        // { src: '~/plugins/Filters.js' }
    ],

    // Auto import components: https://go.nuxtjs.dev/config-components
    components: true,

    // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
    buildModules: [
        '@nuxtjs/device',
        '@nuxtjs/pwa',
    ],

    // Modules: https://go.nuxtjs.dev/config-modules
    modules: [
        // https://go.nuxtjs.dev/bootstrap
        'bootstrap-vue/nuxt',
        '@nuxtjs/axios',
        '@nuxtjs/proxy',
        '@nuxt/content',
    ],

    proxy: {
        '/api': {
            target: 'http://target:81',
            
            pathRewrite: {
                '^/api': '/',
            },
        },
        changeOrigin: true,
    },
    bootstrapVue: {
        // Install the `IconsPlugin` plugin (in addition to `BootstrapVue` plugin)
        icons: true
    },
    // Build Configuration: https://go.nuxtjs.dev/config-build
    build: {
        extend(config, ctx) {
            if (ctx.isDev) {
                config.devtool = ctx.isClient ? 'source-map' : 'inline-source-map'
            }
        },
        
    },

    server: {
        host: '0.0.0.0',
        port: 8000, // default: 3000
    },

    pwa: {
  
        
        manifest: {
            "short_name": "my_project",
            "name": "my_project",
            "background_color": "white",
            "display": "standalone",
            "scope": "/",
            "theme_color": "white"
        },


    }

}

sw.js

importScripts(...[options.workboxURL, ...options.importScripts])

initWorkbox(workbox, options)
workboxExtensions(workbox, options)
precacheAssets(workbox, options)
cachingExtensions(workbox, options)
runtimeCaching(workbox, options)
offlinePage(workbox, options)
routingExtensions(workbox, options)

function getProp(obj, prop) {
  return prop.split('.').reduce((p, c) => p[c], obj)
}

function initWorkbox(workbox, options) {
  if (options.config) {
    // Set workbox config
    workbox.setConfig(options.config)
  }

  if (options.cacheNames) {
    // Set workbox cache names
    workbox.core.setCacheNameDetails(options.cacheNames)
  }

  if (options.clientsClaim) {
    // Start controlling any existing clients as soon as it activates
    workbox.core.clientsClaim()
  }

  if (options.skipWaiting) {
    workbox.core.skipWaiting()
  }

  if (options.cleanupOutdatedCaches) {
    workbox.precaching.cleanupOutdatedCaches()
  }

  if (options.offlineAnalytics) {
    // Enable offline Google Analytics tracking
    workbox.googleAnalytics.initialize()
  }
}

function precacheAssets(workbox, options) {
  if (options.preCaching.length) {
    workbox.precaching.precacheAndRoute(options.preCaching, options.cacheOptions)
  }
}


function runtimeCaching(workbox, options) {
  const requestInterceptor = {
    requestWillFetch({ request }) {
      if (request.cache === 'only-if-cached' && request.mode === 'no-cors') {
        return new Request(request.url, { ...request, cache: 'default', mode: 'no-cors' })
      }
      return request
    },
    fetchDidFail(ctx) {
      ctx.error.message =
        '[workbox] Network request for ' + ctx.request.url + ' threw an error: ' + ctx.error.message
      console.error(ctx.error, 'Details:', ctx)
    },
    handlerDidError(ctx) {
      ctx.error.message =
        `[workbox] Network handler threw an error: ` + ctx.error.message
      console.error(ctx.error, 'Details:', ctx)
      return null
    }
  }

  for (const entry of options.runtimeCaching) {
    const urlPattern = new RegExp(entry.urlPattern)
    const method = entry.method || 'GET'

    const plugins = (entry.strategyPlugins || [])
      .map(p => new (getProp(workbox, p.use))(...p.config))

    plugins.unshift(requestInterceptor)

    const strategyOptions = { ...entry.strategyOptions, plugins }

    const strategy = new workbox.strategies[entry.handler](strategyOptions)

    workbox.routing.registerRoute(urlPattern, strategy, method)
  }
}

function offlinePage(workbox, options) {
  if (options.offlinePage) {
    // Register router handler for offlinePage
    workbox.routing.registerRoute(new RegExp(options.pagesURLPattern), ({ request, event }) => {
      const strategy = new workbox.strategies[options.offlineStrategy]
      return strategy
        .handle({ request, event })
        .catch(() => caches.match(options.offlinePage))
    })
  }
}

function workboxExtensions(workbox, options) {
  
}

function cachingExtensions(workbox, options) {
  
}

function routingExtensions(workbox, options) {
  
}


manifest.json - 在 chrome 调试器上可见

{
  "name": "my_project",
  "short_name": "my_project",
  "icons": [
    {
      "src": "/_nuxt/icons/icon_64x64.64bc82.png",
      "sizes": "64x64",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/_nuxt/icons/icon_120x120.64bc82.png",
      "sizes": "120x120",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/_nuxt/icons/icon_144x144.64bc82.png",
      "sizes": "144x144",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/_nuxt/icons/icon_152x152.64bc82.png",
      "sizes": "152x152",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/_nuxt/icons/icon_192x192.64bc82.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/_nuxt/icons/icon_384x384.64bc82.png",
      "sizes": "384x384",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/_nuxt/icons/icon_512x512.64bc82.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ],
  "start_url": "/?standalone=true",
  "display": "standalone",
  "background_color": "white",
  "theme_color": "white",
  "lang": "en",
  "scope": "/"
}
nuxt.js progressive-web-apps service-worker
1个回答
2
投票

对于任何可能面临此问题的人,@Lawrence Cherone 的评论是正确的;我需要一个有效的证书。 如何使用 MKCert 生成本地证书

  1. 安装MKcert并将其添加到本地根CA

    mkcert -install
    
  2. 为本地应用程序创建证书(在应用程序运行的文件夹中)

    mkcert 192.168.0.2
    
  3. 将证书添加到

    nuxt.config.js

    server: {
       https: {
           key: fs.readFileSync(path.resolve(__dirname, '192.168.0.2-key.pem')),
           cert: fs.readFileSync(path.resolve(__dirname, '192.168.0.2.pem'))
       },
    }
    
  4. 清理浏览器cookies和缓存

  5. 访问

    https://192.168.0.2
    ,等等:可以安装 PWA 添加了

手机使用说明

奖励:对于尝试让它在移动设备上运行的人:

  1. 将您的

    rootCA.pem
    转换为
    rootCA.crt
    如何将pem转换为crt:

    openssl x509 -outform der -in rootCA.pem -out rootCA.crt
    
  2. crt
    证书导入到您的移动设备。 如何在安卓手机上导入CRT。 (可能因设备而异。)

© www.soinside.com 2019 - 2024. All rights reserved.