如何从客户端浏览器的内容中生成并提示保存文件?

2022-01-24 00:00:00 file download save javascript

我有一种情况,我需要让我的用户选择将本地存储在其客户端内存中的一些数据保存到磁盘.我目前的解决方法是有一个这样的处理程序

I have a situation where I need to give my users the option to save some data stored locally in their client memory to disk. The current workaround I have is having a handler like this

(define-handler (download-deck) ((deck :json))
  (setf (header-out :content-type) "application/json"
    (header-out :content-disposition) "attachment")
  deck)

这正是它看起来的样子.客户端发送他们的数据,并将返回的文件保存在本地.

which does exactly what it looks like. The client sends their data up, and saves the returned file locally.

这似乎很愚蠢.

拜托,拜托告诉我,有一种更好、更简单、跨浏览器的方法可以让客户通过文件保存对话框将一些本地数据保存到他们的磁盘上.

Please, please tell me there's a better, simpler, cross-browser way to let a client save some local data to their disk with a file-save dialog box.

我读到的关于该主题的每个答案要么说不,你不能用 javascript 保存文件",要么是是的,Chrome API 有一个半文档化的部分可以让你在三页内完成".

Every answer I read on the subject either says "no, you can't save files with javascript" or "yes, there's this one semi-documented piece of the Chrome API that might let you do it in three pages".

推荐答案

这个FileSaver"库可能会有所帮助.如果你想让它合理地跨浏览器,你还需要 this 来实现W3C Blob API 在尚未实现的地方.两者都尊重命名空间,并且完全与框架无关,所以不用担心命名问题.

This "FileSaver" library may help. If you want it to be reasonably cross-browser, you'll also need this to implement the W3C Blob API in places it's not already implemented. Both respect namespaces, and are completely framework agnostic, so don't worry about naming issues.

一旦你包含了这些,只要你只保存文本文件,你应该能够

Once you've got those included, and as long as you're only saving text files, you should be able to

var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
saveAs(blob, "hello world.txt");

请注意,new Blob 的第一个参数必须是字符串列表,并且您需要指定文件名.如在,用户将看到这个文件正在本地下载,但不能自己命名.希望他们使用的浏览器可以处理本地文件名冲突...

Note that the first argument to new Blob has to be a list of strings, and that you're expected to specify the filename. As in, the user will see this file being downloaded locally, but won't be able to name it themselves. Hopefully they're using a browser that handles local filename collisions...

相关文章