12

When attempting to access a file using the getFile() method of a FileSystemFileHandle, this error can occur: DOMException: The request is not allowed by the user agent or the platform in the current context.

This code works:

async function getTheFile() {
  // open file picker
  [fileHandle] = await window.showOpenFilePicker(pickerOpts);

  // get file contents
  const fileData = await fileHandle.getFile();
}

However if you store the fileHandle (using IndexedDB, for example) with the intent to persist access to the file even after a page refresh, it will not work. After refreshing the page, the getFile() method will throw the DOMException error.

What's going on?

James Gentes
  • 7,528
  • 7
  • 44
  • 64

2 Answers2

16

When the page is refreshed (or all tabs for the app are closed) the browser no longer has permission to access the file.

There is a queryPermission() method available for the FileSystemHandle that can be used to determine whether the file can be accessed before attempting to read it.

Example from a helpful web.dev article:

async function verifyPermission(fileHandle, readWrite) {
  const options = {};
  if (readWrite) {
    options.mode = 'readwrite';
  }
  // Check if permission was already granted. If so, return true.
  if ((await fileHandle.queryPermission(options)) === 'granted') {
    return true;
  }
  // Request permission. If the user grants permission, return true.
  if ((await fileHandle.requestPermission(options)) === 'granted') {
    return true;
  }
  // The user didn't grant permission, so return false.
  return false;
}

This function will return true once the permission === granted or re-prompt the user for access if permission is either denied or prompt.

James Gentes
  • 7,528
  • 7
  • 44
  • 64
0

Note that you will have to grant permissions each time you retrieve a handle from indexedDB, serializing seems to lose the permission

Sceat
  • 1,427
  • 14
  • 12
  • That's true, however I store the `File` object in indexedDB as a cache to avoid prompting the user. Files can be big, so it should be used sparingly. – James Gentes Oct 31 '22 at 15:14