Search code examples
angulargoogle-chromesafarizxing

In production, zxing/ngx-scanner works in Safari but not in Chrome


The bug Despite using HTTPS, Chrome fails to open the zxing/ngx-scanner and receives this error upon attempting to do so: @zxing/ngx-scanner Error when asking for permission. DOMException: Permission denied. However, it works perfectly in Safari. Safari asks if the camera can be accessed, and upon giving it permission, all works well.

I've used boilerplate zxing code from Stackblitz, this repo's documentation, and elsewhere, e.g. <zxing-scanner></zxing-scanner> in an Angular 8 component.html. Even plain <zxing-scanner></zxing-scanner> and nothing else produces this behavior.

To Reproduce Steps to reproduce the behavior: 1. npm i @zxing/ngx-scanner 2. In an Angular 8 project, go to a page with <zxing-scanner></zxing-scanner> in the component.html while in an HTTPS production environment (e.g. deployed to Heroku). 3. No permission will be asked to access the camera in Chrome. 4. Therefore, the scanner won't open, and the console will display the above error. 5. Go to the same page in Safari. The browser asks for permission to access the camera, and the scanner works perfectly.

Expected behavior The scanner works for all browsers, including Chrome, while in production.

Versions

  • OS: Mac 10.14.6
  • Browser: Chrome: 78.0.3904.97
  • Version: @zxing/ngx-scanner 2.0.1
  • Angular 8

Additional context

  • On localhost, everything works great on both Chrome and Safari.
  • Chrome security settings does not show the prod site listed as a security exception.
  • Visiting other people's zxing-scanner pages, e.g. on Stack blitz, while in Chrome shows that the scanner is asking permission as expected and everything is working perfectly. When reproducing the same code in my environment, scanner does not work and gives the above error.
  • If it didn't work in Safari, I'd think that the problem is with my environment because all signs point to that...but it works in Safari. Perhaps there's something about Safari's security that allows this, but even upon disabling Chrome security as per this post, the same error occurs.
  • I'm also using a service-worker (via WorkboxPlugin) for offline access via local caching. I excluded the scanner page and it still does not work.

Solution

  • I had the same situation. Please check your headers... In my .htaccess file I had something like this:

    Header set Feature-Policy "geolocation 'none'; midi 'none'; camera 'none'; usb 'none'; magnetometer 'none'; accelerometer 'none'; vr 'none'; speaker 'none'; ambient-light-sensor 'none'; gyroscope 'none'; microphone 'none'"
    

    as you see:

    camera 'none';
    

    Firefox ignored it, chrome didn't.