【问题标题】:Force showing the "Save as" dialog box when downloading a file下载文件时强制显示“另存为”对话框
【发布时间】:2021-08-20 13:39:16
【问题描述】:

以下代码确实将文件保存到用户的磁盘:

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);
}

它使用<a> 标签来保存一些数据(在我的例子中,是从<canvas> 导出的图像)。

但这会直接保存到磁盘,不会提示询问文件保存在哪里,也不用哪个名称。

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

【问题讨论】:

标签: javascript canvas save-as


【解决方案1】:

没有。

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

当浏览器配置为将下载内容保存到默认文件夹而不提示时,无法说服浏览器显示另存为对话框。这完全在用户的控制之下。

【讨论】:

  • 那么这是否意味着如果没有默认文件夹我可以制作另存为对话框?我很困惑,您的回答完全是“不”和“不可能”。
  • 您可以设置下载。你已经做到了。浏览器可能会将其保存到默认文件夹显示“另存为”对话框,但(网页的开发者)无法控制哪个。
【解决方案2】:

是的,它叫做showSaveFilePicker()

这是File System Access 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 );
  }
}

这是live demo,(和code)。

【讨论】:

  • 哇,太棒了!当我看到现场演示和代码时,我想赶紧把我的代码改编成你的,但作为一个初学者,我认为这需要时间。谢谢你的详细解答。
  • 我修改了你的代码并且它有效!我仍在学习 asynce 并等待......但很高兴学习新事物!这是我的 github 页面,你可以看看我做了什么。我从字面上复制并粘贴你的...github.com/kokiok3/vanilaJs-canvasUpgrade
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多