ファイル読み取りのため、以下のコードをそのまま実行したら動きませんでした。
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のセキュリティのよる制限です。
セキュリティ
Window.showOpenFilePicker() – Web API | MDN
ユーザーによる一時的な有効化が必要です。この機能が動作するには、ユーザーがページまたは UI 要素を操作する必要があります。
このような制限があるのは、ウェブサイトがしつこい画面表示をできないようにするためです。
ユーザーがボタン操作などをしないと画面は表示できないようにロックされています。
挙動が望むものでないとき悪いユーザー体験をもたらす 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);
「ユーザーによる一時的な有効化」は、以下のようなイベントです。