Мне нужно было сделать кнопку экспорта данных со страницы в CSV. При этом нужно было задать осмысленное название файла. Вот такой код, работающий в chome и firefox, решает эту задачу:
const csvHeader = `Type,Id`
// Получаем строку вида "значение,значение,\nзначение,значение"
const csvData = [['type1', 1], ['type2', 2]].map(a => a.join(',')).join('\n')
const csvContent = csvHeader + '\n' + csvData
const downloadFileLink = document.createElement('a')
downloadFileLink.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent)
downloadFileLink.target = '_blank'
downloadFileLink.download = 'fancy-filename.csv'
document.body.appendChild(downloadFileLink) // без добавления в DOM не работает в FF
downloadFileLink.click()
document.body.removeChild(downloadFileLink) // подчищаем за собой узлы
Важно чтобы этот код выполнялся синхронно с кликом пользователя. Тогда пройдет трюк с искусственным кликом по виртуальной ссылке.
На нескольких проектах тоже требовалось подобное. По возможности, пытался делать сам кликабельный элемент ссылкой с прописанным атрибутом download. Тогда в коде останется только подменить href. И нет необходимости программно создавать/прописывать все атрибуты/добавлять в ДОМ, потом удалять из ДОМ. Немного, но сокращает код :)
Но в одном проекте были несколько ограничений
доступ к ресурсам был только на сервере.
составление содержимого было трудоёмкой задачей.
Сперва была попытка просто также синхронно прописывать линку на сервер с параметрами. Но в зависимости от этих параметров зависел и размер. И иногда вычисление переваливало за timeout 😅 Чисто теоретически можно было увеличить его, но решили, что такое поведение неподобающе для хорошего пользовательского опыта.