从弹出窗口调用时,文件系统 API 无法写入文件

问题描述 投票:0回答:1

我有一个应用程序,我想将浏览器生成的数据文件保存在本地磁盘上。有时我可能想在存储之前编辑这些数据,因此我将其显示在弹出窗口的文本区域中。

为了存储数据,调用相同的方法,但是当从弹出窗口调用它时,它会失败,而当从主浏览器窗口调用时,它会成功保存文件。

方法如下

async function storeText(text = "...", win = null){
    if (win == null)
        win = window;

        const options = {
            types: [
                {
                description: 'Text files',
                accept: {
                    'text/plain': ['.txt'],
                },
                },
            ],
            suggestedName: "LoremIpsumFile.txt",
            };
    
    return win.showSaveFilePicker(options).then((fileHandle) =>{
        console.log("got a file handle");
        fileHandle.createWritable().then((writable) =>{
            console.log("Got a writeable object");
            console.log("Text is:\n "+ text);
            writable.write(text).then(()=>{
                console.log("Successfully written, now close");
                writable.close();
            }, (rejectWrite) => {
                console.log("Could not write: " + rejectWrite);
            });
        }, (rejectWritable) =>{
            console.log("Got no writable: " + rejectWritable);
        });
    }, (rejectHandle) =>{
        console.log("Got no handle: " + rejectHandle);
    });
}

如果我从主窗口上的单击事件调用该函数,字符串将正确存储到文件中。

如果从弹出窗口上的按钮调用该函数,则代码将执行直到“获得文件句柄”,但返回不会留下成功或失败的痕迹。 然后将具有给定名称和零字节大小的文件写入磁盘。

可以使用这个 js Fiddle

测试完整的工作示例

注1:虽然小提琴中的弹出行为保持不变,但直接存储的代码将不起作用,因为跨源子帧

注 2:必须将 Window 参数传递给函数,以确保在发生单击事件的同一窗口上调用 showSaveFilePicker() 方法。否则 - 如果简单地调用

window.showSaveFilePicker(options)
- 从弹出窗口调用时会引发安全错误(必须处理用户手势以显示文件选择器

我的问题是:

  • 为什么写入磁盘失败?
  • 为什么我看不到任何有关失败的日志?
javascript promise native-file-system-api-js
1个回答
0
投票

感谢@Raymond Chen 的评论,我发现我想要的东西不可能以我想要的方式实现。 可能的解决方案是:

  1. 不要在本地打开弹出窗口,而是参考 https 上下文上的 PHP 页面 打开它,并将要编辑的数据作为 POST 或 GET 参数传递。
  2. 无需打开弹出窗口,只需将
    div
    放在主窗口中显示的内容顶部即可。使用简单的 CSS
    z-index:100; position:absolute; left:0; top:0;
    div
    位于其他内容之上,不应干扰布局。此选项的缺点是 - 与弹出窗口不同 - 虽然它是可见的,但您无法查看主窗口的其他内容,有时这可能很有用。

由于实现简单,我选择了第二个选项。如果我发现它的缺点变得太烦人,我将来可能会改用第一个。

© www.soinside.com 2019 - 2024. All rights reserved.