微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Electron + Create React App 中使用 File System Access API 写入文件失败

如何解决在 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 调用后的控制台日志在浏览器中显示 truegranted,在 Electron 中显示 truedenied

我尝试在创建 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 举报,一经查实,本站将立刻删除。