在 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 导入模块的主要内容,如果未能解决你的问题,请参考以下文章