Ошибка записи в файлы с использованием API доступа к файловой системе в приложении Electron + Create React
У меня есть приложение create-response-app, которое читает и записывает локальные файлы с помощью API доступа к файловой системе . При запуске в браузере (Chrome или Edge, которые его поддерживают) чтение и запись файлов работают нормально.
Когда приложение запущено в Electron, чтение работает, но запись не выполняется из-за:
Uncaught (in promise) DOMException: The request is not allowed by the user agent or the platform in the current context.
Я использую последнюю версию Electron (12.0.1), в которой используется тот же Chromium (89.0.4389.82), что и в моем браузере Chrome.
Ниже приведен соответствующий код. Журнал консоли после
requestPermission
звонки шоу и
granted
в браузере и
true
и
denied
в электрон.
Я пробовал отключить
webSecurity
при создании
BrowserWindow
, отключение песочницы с помощью
appendSwitch
но ничего не помогло.
Есть ли способ предоставить Chromium in Electron больше разрешений?
Если нет, я готов по-другому обрабатывать запись файлов в Electron. В таком случае, что писать вместо
TODO
в коде? Обратите внимание: поскольку это приложение create-response-app,
fs
модуль недоступен .
export async function chooseAndReadFile() {
const fileHandle = await window.showOpenFilePicker().then((handles) => handles[0])
const file = await fileHandle.getFile()
const contents = await file.text()
return contents
}
export async function chooseAndWriteToFile(contents: string) {
const fileHandle = await window.showSaveFilePicker()
const descriptor: FileSystemHandlePermissionDescriptor = {
writable: true,
mode: "readwrite"
}
const permissionState = await fileHandle.requestPermission(descriptor)
console.log(window.isSecureContext)
console.log(permissionState)
const writable = await fileHandle.createWritable()
await writable.write(contents)
await writable.close()
}
let isElectron = require("is-electron")
export async function chooseAndWriteToFileUniversal(contents: string) {
if (isElectron()) {
// TODO: Do what???
} else {
chooseAndWriteToFile(contents)
}
}
1 ответ
Отвечая на свой вопрос, я наконец использовал решение с HTML
download
атрибут, красиво описанный здесь . Когда этот метод используется в Electron, он представляет диалог сохранения файла, который мне и нужен. При использовании в браузере этот метод просто загружает файл без запроса, поэтому я продолжу использовать API доступа к файловой системе для браузерных сред.
Вот код, который обрабатывает загрузку при работе в Electron.
function download(filename: string, contents: string) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(contents));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
let isElectron = require("is-electron");
export async function chooseAndWriteToFileUniversal(contents: string) {
if (isElectron()) {
download("data.txt", contents)
} else {
chooseAndWriteToFile(contents) // See the original question for implementation of this function
}
}
Тем не менее, было бы неплохо узнать, почему / как Chromium в Electron более ограничен, чем в обычном браузере Chrome или Edge, и можно ли его изменить.