codinggames

Como criar um link para download de um JSON apenas com HTML

Escrito em 9 de maio de 2021 - 🕒 2 min. de leitura

Essa semana eu estava trabalhando no meu projeto Resume Builder e eu queria poder criar um botão que fizesse o download de um JSON sem usar JavaScript.

A única maneira que eu sabia fazer isso era usando URL.createObjectURL em um arquivo blob, mas isso não funcionaria para mim, porque este link estaria dentro de um arquivo PDF.

Então eu fiz a primeira coisa que qualquer millennial faria, pesquisei no Stack Overflow, mas não consegui encontrar nada… como isso é possível? Bom, de qualquer maneira, depois de algumas tentativas, consegui fazer o que eu queria usando Base 64.

Digamos que eu queira criar um botão de download que baixará JSON {foo: 'bar'}, primeiro precisamos convertê-lo para uma string em Base 64, podemos fazer isso com a função btoa do JavaScript:

const json = { foo: 'bar' };
const jsonString = JSON.stringify(json);
const base64Json = btoa(jsonString); // eyJmb28iOiJiYXIifQ==

Ok, agora que sei qual é o valor Base 64 para o objeto {foo: 'bar'}, posso criar um elemento anchor da seguinte maneira:

<a href="data:application/json;base64,eyJmb28iOiJiYXIifQ==" download="object.json">download</a>

E isso é tudo. No meu caso, eu só precisava que o código fosse servido como HTML e, como estou usando Gatsby, o código real que eu fiz foi um elemento React que será pre-renderizado usando SSR para o meu arquivo PDF:

const DownloadJsonLink = ({
    children,
    json = {},
    name = 'object.json',
}) => {
    const href = useMemo(
        () => {
            if (typeof window !== 'undefined') {
                const base64Data = btoa(unescape(encodeURIComponent(JSON.stringify(json))));
                return `data:application/json;base64,${base64Data}`;
            }

            return '#';
        },
        [json]
    );

    return (
        <a
            href={href}
            download={name}
            target="_blank"
        >
            {children}
        </a>
    );
};

export default DownloadJsonLink;

Eu sabia que era possível fazer isso para baixar uma imagem, mas nunca tinha tentado para outros tipos de arquivos.

Incrível ainda aprender coisas de HTML mesmo depois de muitos anos de experiência e espero que mais alguém aprenda algo novo com esse post, até a próxima pessoal.

Tags:


Publicar um comentário

Comentários

Nenhum comentário.