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

kko*_*kki 4 javascript canvas save-as

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Kai*_*ido 13

是的,它的名字叫showSaveFilePicker().

这是文件系统访问API的一部分,该 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 );
  }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这很棒,但目前[浏览器支持](https://developer.mozilla.org/en-US/docs/Web/API/Window/showSaveFilePicker#browser_compatibility)非常有限。 (2认同)