Доступ к контексту / миру / среде службы любого сайта для самостоятельной регистрации прокси.Уведомление о показе с помощью дополнения браузера?

#javascript #notifications #service-worker #firefox-addon-webextensions #proxy-pattern

#javascript #уведомления #service-worker #firefox-addon-webextensions #прокси-шаблон

Вопрос:

Я хотел бы создать расширение для браузера, которое по своей сути проксирует registration.showNotification функцию фильтрации на основе правил, установленных в аддоне. Проксирование window.Notification тривиально, но у меня возникают проблемы даже с решением проблемы. Я знаю, что могу получить регистрацию работника службы, но переназначение showNotification не кажется постоянным и, похоже, на самом деле не работает, за исключением случаев, когда я вызываю функцию через консоль.

Моя идея «последнего средства» (которая кажется сложной) — перехватывать и изменять входящие запросы для изменения showNotification функции через window.postMessage или что-то подобное — но я хочу, чтобы это было последним средством.

Есть ли какой-либо мыслимый способ сделать то, что я пытаюсь сделать здесь? Или, может быть, API, которого мне не хватает? Основываясь на моих исследованиях, пока я предполагаю, что нет. Я не самый опытный специалист в области JS, поэтому я подумал, что попробую ответить на этот вопрос. Я использую Firefox, если это имеет значение.

Комментарии:

1. какую версию Firefox вы используете? showNotification не работает до FF78

Ответ №1:

В магазине дополнений Firefox есть аналогичное расширение Service Worker Control, и вы можете найти его источник здесь, под лицензией MPL.

Теперь, более конкретно, я понимаю, что вы хотите перехватить или изменить showNotification функцию, что может быть достигнуто с помощью чего-то похожего на приведенный ниже код (фрагмент, адаптированный из приведенного выше источника):

 const showNotification_backup = ServiceWorkerRegistration.prototype.showNotification

function showNotification(title, options) {
    const obj = { type: 'notification', isInjected }
    try {
        const sw = this.installing || this.waiting || this.active
        obj.url = typeof sw === 'object' amp;amp; sw ? ''   sw.scriptURL : undefined
    } catch { }
    try { obj.scope = ''   this.scope } catch { }
    try { obj.title = ''   title } catch { }
    try { obj.body = ''   options.body } catch { }
    send(obj)
    return showNotification_backup.apply(this, arguments)
}

if (setupCondition) {
    ServiceWorkerRegistration.prototype.showNotification = showNotification
} else {
    exportFunction(showNotification, ServiceWorkerRegistration.prototype,
            { defineAs: 'showNotification' })
}
 

где exportFunction является частью XPCOM API, таким образом изменяя прототип ServiceWorker.

Редактировать

Как упоминалось в комментариях, XPCOM устарел и почти полностью устарел, оставляя вам только изменение прототипа регистрации service worker, как показано ниже:

 let registrations = await navigator.serviceWorker.getRegistrations()

if (registrations.length > 0) {
    Object.getPrototypeOf(registrations[0]).showNotification = showNotification
}
 

Это действительно напрямую изменяет метод цепочки прототипов, что не является хорошей практикой JS, однако, учитывая, что данная showNotification функция применяет аргументы к исходной, она несколько расширяет ее.

Комментарии:

1. «XPCOM больше не доступен для использования расширениями Firefox. Вместо этого используйте WebExtensions. » Как неудачно!