首页 > 解决方案 > 下载文件时强制显示“另存为”对话框

问题描述

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

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>标签来保存一些数据(在我的例子中,是从 a 导出的图像<canvas>)。

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

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

标签: javascriptcanvassave-as

解决方案


是的,它被称为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 );
  }
}

这是一个现场演示,(和代码)。


推荐阅读