Como gerar e solicitar para salvar um arquivo de conteúdo no navegador do cliente?

Eu tenho uma situação onde eu preciso dar aos meus usuários a opção de salvar alguns dados armazenados localmente na memory do cliente para o disco. A solução atual que tenho é ter um manipulador como este

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

que faz exatamente o que parece. O cliente envia seus dados para cima e salva o arquivo retornado localmente.

Isso parece estúpido.

Por favor, diga-me que existe uma maneira melhor, mais simples, entre navegadores, de permitir que um cliente salve alguns dados locais em seu disco com uma checkbox de diálogo para salvar arquivos.

Toda resposta que eu leio sobre o assunto diz “não, você não pode salvar arquivos com javascript” ou “sim, há uma parte semi-documentada da API do Chrome que pode permitir que você faça isso em três páginas”.

Esta biblioteca “FileSaver” pode ajudar . Se você quiser que ele seja razoavelmente compatível com vários navegadores, você também precisará disso para implementar a API de Blobs do W3C em locais que ainda não foram implementados. Ambos respeitam namespaces e são completamente agnósticos em framework, então não se preocupe em nomear problemas.

Uma vez que você tenha aqueles incluídos, e contanto que você esteja apenas salvando arquivos de texto, você deve ser capaz de

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

Note que o primeiro argumento para o new Blob deve ser uma lista de strings, e é esperado que você especifique o nome do arquivo. Da mesma forma, o usuário verá esse arquivo sendo baixado localmente, mas não conseguirá nomeá-lo por conta própria. Espero que eles estejam usando um navegador que lida com colisões de nomes de arquivos locais …

Este é o meu código:

 Export document.getElementById('tfa_src_data').onclick = function() { var csv = JSON.stringify(localStorage['savedCoords']); var csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv); this.href = csvData; this.target = '_blank'; this.download = 'filename.txt'; }; 

Você pode usar vários tipos de dados.

Dependendo do que você está tentando fazer exatamente, o conceito de armazenamento local em HTML5 pode ajudá-lo.

Então, o que é armazenamento HTML5? Simplificando, é uma maneira de as páginas da Web armazenarem pares de chave / valor nomeados localmente, no navegador da web do cliente. Como os cookies, esses dados persistem mesmo depois de você sair do site, fechar a guia do navegador, sair do navegador ou o que você tem. Ao contrário dos cookies, esses dados nunca são transmitidos para o servidor da Web remoto (a menos que você se desvie de seu caminho para enviá-los manualmente). http://diveintohtml5.info/storage.html

Há também a API do sistema de arquivos (até agora só implementada no Chrome AFAIK) http://www.html5rocks.com/en/tutorials/file/filesystem/