在 Service Worker 中从 HTTPS 导入模块

Posted

技术标签:

【中文标题】在 Service Worker 中从 HTTPS 导入模块【英文标题】:Import modules from HTTPS in a Service Worker 【发布时间】:2021-11-09 06:19:02 【问题描述】:

我正在尝试使用他们的 v9 SDK 为 web 实现 Firebase Cloud Messaging,该 SDK 使用 javascript 模块大力推动......我需要在 Vue 组件中注册服务工作者。

服务人员一直在尖叫“你不能在模块之外使用 import 语句”。所以,我尝试将type: 'module' 选项添加到navigator.serviceWorker.register 调用中......但没有运气。我还尝试了老式的importScripts 无济于事。少数在线示例显示 <script type='module'> 但这在 Vue 组件内部毫无意义,至少从我的理解来看是这样。

这是服务工作者的全部内容:

import  fbConfig  from "/js/firebase/firebase-config.js";
import  initializeApp  from "https://www.gstatic.com/firebasejs/9.0.2/firebase-app.js"
import  getMessaging, onBackgroundMessage  from "https://www.gstatic.com/firebasejs/9.0.2/firebase-messaging-sw.js"

// Create the instance of Firebase & Messaging
const fbApp = initializeApp(fbConfig)
const messaging = getMessaging(fbApp);

onBackgroundMessage(messaging, (payload) => 
    console.log('[firebase-messaging-sw.js] Received background message ', payload);

    const notificationTitle = payload.message.notification.title;
    const notificationOptions = payload.message.notification.body;

    let outcome = self.registration.showNotification(
        notificationTitle,
        notificationOptions
    );
    console.log('[firebase-messaging-sw.js] showNotification outcome', outcome)
);

这是我尝试注册它的地方,它位于我的 Vue 组件的“mounted()”部分中:

        if ('serviceWorker' in navigator) 
            navigator.serviceWorker.register(
                '/firebase-messaging-sw.js', 
                    type: 'module'
                )
                .then(reg => 
                    console.log(`Service Worker Registration (Scope: $reg.scope)`);
                )
                .catch(error => 
                    const msg = `Service Worker Error ($error)`;
                    console.error(msg);
                );
         else 
            // happens when the app isn't served over HTTPS or if the browser doesn't support service workers
            console.warn('Service Worker not available');
        

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

你能用这个代码试试看吗:


importScripts('/__/firebase/9.0.1/firebase-app-compat.js');
importScripts('/__/firebase/9.0.1/firebase-messaging-compat.js');
importScripts('/__/firebase/init.js');

const messaging = firebase.messaging();

messaging.onBackgroundMessage(function(payload) 
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  const notificationTitle = 'Background Message Title';
  const notificationOptions = 
    body: 'Background Message body.',
    icon: '/firebase-logo.png'
  ;

  self.registration.showNotification(notificationTitle,
    notificationOptions);
);

【讨论】:

谢谢,但 Firebase 不同意。我将整个 onBackgroundMessage 方法调用连同它的导入一起移到了我的 Vue 组件中,并收到以下错误消息:vue.esm.js?a026:628 [Vue warn]: Error in mounted hook: "FirebaseError: Messaging: This method is available in a service worker context. (messaging/only-available-in-sw)." 你能试试答案中的新代码吗?它使用新 SDK 的compat 版本,但想看看它是否正常工作。它无法在调试模式下工作,因为导入需要来自 Firebase 托管。 完成...但似乎我处于第 22 阶段。先前的错误是在模块之外不允许导入语句。新错误是模块不支持 importScripts。我完全糊涂了。完全错误:Uncaught TypeError: Failed to execute 'importScripts' on 'WorkerGlobalScope': Module scripts don't support importScripts(). 老实说,我开始认为 Google/Firebase 的人们不知何故错过了这个特定的用例......(NPM 可用于 Vue 前端,无法捆绑消息传递所需的服务工作者浏览器在后台。)

以上是关于在 Service Worker 中从 HTTPS 导入模块的主要内容,如果未能解决你的问题,请参考以下文章

在Service Worker中抛出错误“Uncaught(in promise)DOMException”

vue 中使用 Service Worker 遇到的问题

使用自签名证书在 chrome android 上远程调试 service worker

Chrome 拓展开发 Service Worker 无法使用 XMLHttpRequest 发送 HTTP 请求

web worker 与 service worker

如何通过 cdn 脚本注册 service worker。如何使用外部 url 注册 service worker