【スポンサーリンク】

[JavaScript] showOpenFilePickerがエラーになる(Uncaught (in promise) DOMException)

ファイル読み取りのため、以下のコードをそのまま実行したら動きませんでした。

      const pickerOpts = {
        types: [{ description: 'Texts(.txt)', accept: {'text/*': ['.txt']} }],
        multiple: false,
      }
      let fileHandle;
      [fileHandle] = await window.showOpenFilePicker(pickerOpts);
      
      const file = await fileHandle.getFile();
      const fileContents = await file.text();
      console.log(fileContents);

コンソールをみると、エラーが表示されています。

Uncaught (in promise) DOMException: Failed to execute ‘showOpenFilePicker’ on ‘Window’: Must be handling a user gesture to show a file picker.

キャッチされません (約束どおり) DOMException: ‘Window’ で ‘showOpenFilePicker’ の実行に失敗しました: ファイル ピッカーを表示するにはユーザー ジェスチャを処理している必要があります。

ファイル ピッカーを表示するには ユーザー ジェスチャを処理している必要があります」というのは、JavaScriptのセキュリティのよる制限です。

セキュリティ
ユーザーによる一時的な有効化が必要です。この機能が動作するには、ユーザーがページまたは UI 要素を操作する必要があります。

Window.showOpenFilePicker() – Web API | MDN

このような制限があるのは、ウェブサイトがしつこい画面表示をできないようにするためです。
ユーザーがボタン操作などをしないと画面は表示できないようにロックされています。

挙動が望むものでないとき悪いユーザー体験をもたらす API をアプリケーションに濫用させないため、ユーザーが「アクティブに操作中」の状態、すなわちユーザーが現在ウェブページを操作しているか、もしくは少なくとも 1 回ページを操作したか、のときのみ使用可能な API があります。ブラウザーは、悪意のあるスクリプトがこれらの機能を濫用するのを防ぐため、ポップアップ、フルスクリーン、振動などの機微な API へのアクセスを制限します。

ユーザーによる有効化によって制御される機能 – ウェブセキュリティ | MDN

実行するには、直前にユーザー操作のイベントを受け取ればよいです。

たとえば、ブラウザでのキー操作を受け取れば実行できました。

      var fileSelect = async function(event) {

        if (event.keyCode==32) {
          const pickerOpts = {
            types: [{ description: 'Texts(.txt)', accept: {'text/*': ['.txt']} }],
            multiple: false,
          }
          let fileHandle;
          [fileHandle] = await window.showOpenFilePicker(pickerOpts);
          
          const file = await fileHandle.getFile();
          const fileContents = await file.text();
          console.log(fileContents);
          window.removeEventListener('keydown', fileSelect); 
        }
      };
      window.addEventListener('keydown', fileSelect); 

「ユーザーによる一時的な有効化」は、以下のようなイベントです。

  • isTrusted 属性が true に設定されており、
  • かつ、以下の種類のイベントである
    • keydown (Esc およびユーザーエージェントによって予約されているショートカットキーを除く)
    • mousedown
    • pointerdown (pointerType が “mouse” であるとき)
    • pointerup (pointerType が “mouse” でないとき)
    • touchend
QRコードを読み込むと、関連記事を確認できます。
[JavaScript] showOpenFilePickerがエラーになる(Uncaught (in promise) DOMException)
【スポンサーリンク】
タイトルとURLをコピーしました