强制显示“另存为”对话框以下载文件

3
以下代码会将文件保存到用户的磁盘中:
function handleSaveImg(event){
  const image = canvas.toDataURL();
  const saveImg = document.createElement('a');
  saveImg.href = image;
  saveImg.download= saveAs;
  saveImg.click();
}

if(saveMode){
  saveMode.addEventListener("click", handleSaveImg);
}

它使用标签保存一些数据(在我的情况下,是从导出的图像)。

但是这会直接保存到磁盘上,没有提示要求在哪里保存文件,也没有提示文件名。

我想强制显示“另存为”对话框,以便用户必须选择保存文件的位置。
有什么办法吗?


2个回答

13

是的,它被称为showSaveFilePicker()

这是文件系统访问API的一部分,目前仍处于草案阶段,但已在所有Chromium浏览器中公开。

该API非常强大,可以直接访问用户的磁盘,因此仅在安全上下文中可用。

一旦此方法返回的Promise解决了,您将获得一个句柄,从中您将能够访问一个WritableStream,您将能够向其中写入数据。

download相比,它要复杂一些,但也更加强大,因为您可以像流一样写入数据,而不需要将整个数据存储在内存中(想想录制视频)。

在您的情况下,这将提供:

async function handleSaveImg(event){
  const image = await new Promise( (res) => canvas.toBlob( res ) );
  if( window.showSaveFilePicker ) {
    const handle = await showSaveFilePicker();
    const writable = await handle.createWritable();
    await writable.write( image );
    writable.close();
  }
  else {
    const saveImg = document.createElement( "a" );
    saveImg.href = URL.createObjectURL( image );
    saveImg.download= "image.png";
    saveImg.click();
    setTimeout(() => URL.revokeObjectURL( saveImg.href ), 60000 );
  }
}

这里有一个实时演示(以及代码)。


哇,太棒了!当我看到实时演示和代码时,我真想赶紧把我的代码改成你的,但作为一个初学者,我觉得这需要一些时间。非常感谢你详细的回答。 - undefined
1
我适应了你的代码,它工作了!我还在学习异步和等待... 但非常高兴学到新东西!这是我的 GitHub 页面,你可以看看我做的东西。我简直是复制粘贴了你的... https://github.com/kokiok3/vanilaJs-canvasUpgrade - undefined
这个非常厉害;你真是一个传奇 - undefined
2
这很棒,但目前在浏览器支持方面非常有限。 - undefined

0

不行。

您可以通过将字符串分配给download属性来指定文件名。

如果浏览器配置为将下载保存到默认文件夹而不提示,则无法说服浏览器显示SaveAs对话框。这完全由用户控制。


那么这意味着如果没有默认文件夹,我可以创建“另存为”对话框吗?我有点困惑,你的回答完全是否定的,毫无余地。 - undefined
1
你可以设置一个下载。你已经做到了这一点。浏览器可能会将其保存到默认文件夹,或者显示一个“另存为”对话框,但是(作为网页开发者的)你无法控制它保存到哪里。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接