最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Undefined is not an object (evaluating 'navigator.permissions.query') - Stack Overflow

programmeradmin3浏览0评论

I am getting this error when trying to access my website on an iPhone 7, with a white bank screen (the main screen loads fine, but then I get this at the net screen after I click something.

I assume this is what it's talking about:

  useEffect(() => {
    navigator.permissions
      .query({ name: "microphone" })
      .then((permissionStatus) => {
        setMicrophonePermissionGranted(permissionStatus.state === "granted");

        permissionStatus.onchange = function () {
          setMicrophonePermissionGranted(this.state === "granted");
        };
      });

    navigator.permissions.query({ name: "camera" }).then((permissionStatus) => {
      setCameraPermissionGranted(permissionStatus.state === "granted");

      permissionStatus.onchange = function () {
        setCameraPermissionGranted(this.state === "granted");
      };
    });
  }, []);

How do I fix this?

I am getting this error when trying to access my website on an iPhone 7, with a white bank screen (the main screen loads fine, but then I get this at the net screen after I click something.

I assume this is what it's talking about:

  useEffect(() => {
    navigator.permissions
      .query({ name: "microphone" })
      .then((permissionStatus) => {
        setMicrophonePermissionGranted(permissionStatus.state === "granted");

        permissionStatus.onchange = function () {
          setMicrophonePermissionGranted(this.state === "granted");
        };
      });

    navigator.permissions.query({ name: "camera" }).then((permissionStatus) => {
      setCameraPermissionGranted(permissionStatus.state === "granted");

      permissionStatus.onchange = function () {
        setCameraPermissionGranted(this.state === "granted");
      };
    });
  }, []);

How do I fix this?

Share Improve this question asked Apr 23, 2020 at 13:17 TsabaryTsabary 3,9885 gold badges40 silver badges92 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

You need to check permission APIs availability and then if not available - query standard APIs.

Here is the location example: Permissions API Navigation API

if ( navigator.permissions && navigator.permissions.query) {
//try permissions APIs first
  navigator.permissions.query({ name: 'geolocation' }).then(function(result) {
      // Will return ['granted', 'prompt', 'denied']
      const permission = result.state;
      if ( permission === 'granted' || permission === 'prompt' ) {
          _onGetCurrentLocation();
      }
  });
} else if (navigator.geolocation) {
//then Navigation APIs
  _onGetCurrentLocation();
}

function _onGetCurrentLocation () {
    navigator.geolocation.getCurrentPosition(function(position) {
        //imitate map latlng construct
        const marker = { 
          lat: position.coords.latitude, 
          lng: position.coords.longitude 
        };
    })
}

Permissions.query() is marked as an experimental feature as of June 2021 https://developer.mozilla/en-US/docs/Web/API/Permissions/query.

As of today, that traduces into that you'll need to implement two UIs / flows; one capable of supporting fancy flows to tell the user how to proceed, and the other one more standard, using try / catch blocks. Something like:

useEffect(() => {
    requestPermissions();
}, []);

const requestPermissions = async () => {
    try {
        handlePermissionsGranted();
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
        startRecording();
    } catch {
        ...
    }
};

const handlePermissionsGranted = async () => {
    if (navigator.permissions && navigator.permissions.query) {
        const permissions = await navigator.permissions.query({name: 'microphone'});
        permissions.onchange = () => {
          setMicrophonePermissionGranted(permissions === 'granted');
        };
    } 
};

const startRecording = async () => {
    try {
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
        const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });
        ...
    } catch {
        ... << if you reach this catch means that either the browser does not support webrtc or that the user didn't grant permissions
    }
};

I was trying to check for the mic and camera permissions from iOs devices and through the Facebook browser, which I guess makes the whole thing fail, as these don't exist in those environments. Once I've moved that query to the ponent that only loads if it is not a mobile device, my error fixed.

发布评论

评论列表(0)

  1. 暂无评论