New issue
Advanced search Search tips

Issue 680493 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner: ----
Closed: Jan 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Failing to send a message to ServiceWorker even if it's ready

Project Member Reported by marja@chromium.org, Jan 12 2017

Issue description

I'm probably just doing something stupid, but, as requested, here's a bug report :)

Chrome Version: (copy from chrome://version)

Chromium	57.0.2978.0 (Developer Build) (64-bit)
Revision	8bedca0b30c55f439af1f13f580dcfb352856d8b-refs/heads/master@{#442545}


What steps will reproduce the problem?
(1)

This is the page:

index.html

<head>
  <script>
    function installServiceWorker() {
      console.log("Page: install service worker");
      navigator.serviceWorker.register('serviceworker.js', {scope: './'})
      .then(function(reg) {
        console.log("Page: Registration succeeded. Scope is " + reg.scope);
        navigator.serviceWorker.ready.then(function() { console.log("Page: service worker ready"); });
    }).catch(function(error) {
        // registration failed
        console.log("Page: Registration failed with " + error);
      });
    }
    setTimeout(installServiceWorker, 0);

    function sendMessage() {
      console.log("Page: sending a message to the service worker");
      console.log(navigator.serviceWorker.ready);
      console.log(navigator.serviceWorker.controller);
      navigator.serviceWorker.controller.postMessage("Hello worker");
    }

  </script>
</head>
<body>
  ServiceWorker demo
<button onclick='sendMessage()'>Send message</button>
</body>

--------

serviceworker.js:

console.log("serviceworker js running");

this.addEventListener('install', function(event) {
  console.log("SW: Install");
});

self.addEventListener("message", function(event) {
  console.log("SW: got message");
} );


(2) Start Chromium w/ a fresh user data dir; load the page, wait some seconds, then click the "Send message" button.

(3) Open dev tools to see console messages.

What is the expected result?

The page manages to send a message to the service worker.

What happens instead?

navigator.serviceWorker.controller is null, so we get:

Uncaught TypeError: Cannot read property 'postMessage' of null
    at sendMessage ((index):21)
    at HTMLButtonElement.onclick ((index):28)


-----------------

Full console output:

Page: install service worker
serviceworker.js:2 serviceworker js running
(index):8 Page: Registration succeeded. Scope is http://redacted.google.com/serviceworker-fail/
serviceworker.js:5 SW: Install
(index):9 Page: service worker ready
(index):18 Page: sending a message to the service worker
(index):19 Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: ServiceWorkerRegistration}
(index):20 null
(index):21 Uncaught TypeError: Cannot read property 'postMessage' of null
    at sendMessage ((index):21)
    at HTMLButtonElement.onclick ((index):28)

(Note that I'm using --unsafely-treat-insecure-origin-as-secure; but the problem shouldn't be that, since the service worker manages to get registered and run.)

 

Comment 1 by falken@chromium.org, Jan 12 2017

Status: WontFix (was: Untriaged)
Yea this is a common gotcha. When a page does not have a controller at load time, it will never have a controller, even if a service worker becomes active later on. The basic rule is "a page lives and dies with the same service worker".

The exceptions to the rule are using claim() and skipWaiting(), to control a page that is not currently controlled, or do force the .waiting worker to become .active and the controller.

Closing as WontFix, but feel free to reply if this doesn't address your issue.

Comment 2 by falken@chromium.org, Jan 12 2017

(So the way to fix the code is to use navigator.serviceWorker.ready.then(registration => { registration.active.postMessage(); } rather than .controller.)

Comment 3 by marja@chromium.org, Jan 12 2017

Thanks, that fixes it!

Sign in to add a comment