在 PWA 应用中使用 webworker 的问题与解决方法

随着 PWA(Progressive Web Apps)的兴起,越来越多的网页应用开始使用 webworker 来加速运行或提高用户体验。但是在 PWA 应用中使用 webworker 常会出现一些问题,这篇文章将会详细介绍这些问题及其解决方法。

问题一: 跨域问题

在 PWA 应用中,由于使用了 Service Worker,因此 webworker 也必须在 Service Worker 中运行。但是如果 webworker 想要访问其他域名的资源,往往会遇到跨域问题。

解决方法:

  1. 让服务器添加 CORS 头部

在 webworker 中,可以通过 XMLHttpRequest 来请求其他域名的资源。如果服务器在响应中添加了 CORS 头部,浏览器则会认为该服务器允许跨域请求,从而避免跨域问题。

  1. 使用 iframe 代理

如果服务器无法添加 CORS 头部,可以尝试使用 iframe 代理的方式访问资源。具体做法是创建一个隐藏的 iframe,并将 iframe 的 src 属性设置为代理页面的 URL。代理页面可以在相同的域名下,并通过 iframe.contentWindow.postMessage() 方法来传递数据。

// 在web worker中通过iframe代理访问其他域名的资源
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
const proxyUrl = 'https://example.com/proxy?url=' + encodeURIComponent('https://example.com/data');
iframe.src = proxyUrl;
window.addEventListener('message', function(event) {
  if (event.origin !== 'https://example.com') return;
  console.log(event.data);
});

问题二:与 IndexedDB 交互的问题

在 PWA 应用中, IndexedDB 常被用来存储数据。但是在 webworker 中直接访问 IndexedDB 将会报错,因为 IndexedDB 属于浏览器的主线程。因此我们需要查找交互的方法。

解决方法:

  1. 使用 postMessage 传递消息

在 Service Worker 中可以通过 postMessage 方法来向 webworker 发送消息,同时也可以接收 webworker 发送过来的消息。利用这个机制,我们可以在 Service Worker 中向 IndexedDB 中写入数据,然后通过 postMessage 方法将数据传递给 webworker。

  1. 利用 Blob 和 Worker

在 Service Worker 中创建一个 Blob 对象,通过 URL.createObjectURL() 方法生成一个 URL,然后将 URL 传递给 webworker 中创建的 Worker 对象,这样 webworker 就可以通过该 URL 访问 Service Worker 中的 Blob 对象,从而与 IndexedDB 交互。

// 在 Service Worker 中发送消息
self.addEventListener('message', function(event) {
  const db = event.target.result;
  const tx = db.transaction('store', 'readwrite');
  const store = tx.objectStore('store');
  const request = store.put({ key: 'value' });
  request.onsuccess = function() {
    const message = { type: 'INSERTED' };
    event.ports[0].postMessage(message);
  };
});

// 在web worker中接收消息
const worker = new Worker('worker.js');
worker.postMessage({ type: 'INSERT' });
worker.onmessage = function(event) {
  console.log(event.data);
};

总结

在 PWA 应用中使用 webworker 可以提高应用的性能和用户体验,但是需要注意跨域问题和与 IndexedDB 的交互问题。本文介绍了解决这些问题的方法,希望对 PWA 开发者有所帮助。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a9e50dadd4f0e0ff35a310


纠错反馈