如何解决在 Electron + Create React App 中使用 File System Access API 写入文件失败
我有一个使用 File System Access API 读写本地文件的 create-react-app。在浏览器(支持它的 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),它使用与 Chrome 浏览器中相同的 Chromium (89.0.4389.82)。
以下是相关代码。 requestPermission
调用后的控制台日志在浏览器中显示 true
和 granted
,在 Electron 中显示 true
和 denied
。
我尝试在创建 webSecurity
时禁用 browserWindow
,使用 appendSwitch
禁用沙箱但没有任何帮助。
有没有办法给 Electron 中的 Chromium 更多权限?
如果没有,我愿意在 Electron 中以不同的方式处理文件写入。在这种情况下,在代码中用什么来代替 Todo
?请注意,因为它是一个 create-react-app,所以 fs
模块是 not available。
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)
}
}
解决方法
回答我自己的问题,我终于使用了一个带有 HTML download
属性的解决方案,很好地描述了 here。在 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
}
}
不过,很高兴知道 Electron 中的 Chromium 为什么/如何比普通 Chrome 或 Edge 浏览器中的 Chromium 受到更多限制,以及是否可以更改。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。