Prog blog

How to fix video Safari issue in Angular

How to fix video Safari issue in Angular

I started to add videos showing the operation of some of the solutions I describe on my blog. Something came to see how the entry aboutWeb share buttonworks on Safair. And it turned out that the video is not loading :/. After a long investigation, it turned out that Angular Service Worker has a bug in itself and does not send the headerRangewhen responding to requests for video in the Safair browser. Below I describe a workaround I found ongithub.

A list of steps to workaround the problem.

  1. Install apatch-package.

    npm i patch-package

  2. Add apatch-packagetopostinstall.

    ./package.json

    { 
      "scripts": {
        "postinstall": "patch-package"
      }
    }
  3. Add a patch for the@angular/service-workerpackage.

    ./patches/@angular+service-worker+8.2.14.patch

    diff --git a/node_modules/@angular/service-worker/ngsw-worker.js b/node_modules/@angular/service-worker/ngsw-worker.js
    index 0d185a8..f4fc756 100755
    --- a/node_modules/@angular/service-worker/ngsw-worker.js
    +++ b/node_modules/@angular/service-worker/ngsw-worker.js
    @@ -1925,6 +1925,10 @@ ${msgIdle}`, { headers: this.adapter.newHeaders({ 'Content-Type': 'text/plain' }
              */
            onFetch(event) {
                const req = event.request;
    +            // PATCH to prevent caching certain kinds of requests
    +            // - PUT requests which breaks files upload
    +            // - requests with 'Range' header which breaks credentialed video requests
    +            if (req.method==="PUT" || !!req.headers.get('range')) return;
                const scopeUrl = this.scope.registration.scope;
                const requestUrlObj = this.adapter.parseUrl(req.url, scopeUrl);
                if (req.headers.has('ngsw-bypass') || /[?&]ngsw-bypass(?:[=&]|$)/i.test(requestUrlObj.search)) {
  4. Runnpm install

After these steps you can enjoy working videos on safari. The patch cares in such a way that for requests where you need theRangeService Worker does not try to cache them (in other words, it works like angsw-baypass).