Как создать динамический файл + ссылку для скачивания в Javascript?

Как правило, страницы HTML могут содержать ссылки на документы (PDF и т. Д.), Которые можно загрузить с сервера.

Предполагая, что веб-страница с поддержкой Javascript, возможно ли динамически создать текстовый документ (например) из пользовательского браузера и добавить ссылку для загрузки этого документа без обращения к серверу (или минимального)?

Другими словами, пользователь нажимает кнопку, javascript генерирует случайные числа (например) и помещает их в структуру. Затем javascript (например, JQuery) добавит ссылку на страницу для загрузки результата в виде текстового файла из структуры.

Эта цель - сохранить всю (или, по крайней мере, большую часть) рабочей нагрузки на стороне пользователя.

Возможно ли это, если да, то как?


person Jérôme Verstrynge    schedule 29.11.2011    source источник
comment
теперь 2015 мы можем использовать Blob (Ссылка MDN) для создания URL для загрузки любых данных, созданных динамически.   -  person befzz    schedule 19.06.2015


Ответы (3)


Добавив на страницу URI данных, вы можете встроить на страницу документ, который можно загрузить. . Часть данных строки может быть динамически объединена с помощью Javascript. Вы можете выбрать форматирование в виде строки в кодировке URL или в формате base64. Если он закодирован в формате base64, браузер загрузит его содержимое в виде файла. Вам нужно будет добавить скрипт или плагин jQuery для кодирования. Вот пример со статическими данными:

jQuery('body').prepend(jQuery('<a/>').attr('href','data:text/octet-stream;base64,SGVsbG8gV29ybGQh').text('Click to download'))
person Nate Barr    schedule 29.11.2011
comment
Это не будет работать в IE и Edge: caniuse.com/#feat=datauri - person Limon Monte; 18.10.2015
comment
Это неверно. Он будет работать в IE и Edge для ссылок для скачивания. Он не будет работать в IE / Edge для ресурсов страницы, таких как файлы HTML и CSS. Вы можете загрузить CSS, но не использовать его в теге <link>. - person pseudosavant; 02.08.2016

Вот созданное мной решение, которое позволяет вам создавать и загружать файл за один клик:

<html>
<body>
    <button onclick='download_file("my_file.txt", dynamic_text())'>Download</button>
    <script>
    function dynamic_text() {
        return "create your dynamic text here";
    }

    function download_file(name, contents, mime_type) {
        mime_type = mime_type || "text/plain";

        var blob = new Blob([contents], {type: mime_type});

        var dlink = document.createElement('a');
        dlink.download = name;
        dlink.href = window.URL.createObjectURL(blob);
        dlink.onclick = function(e) {
            // revokeObjectURL needs a delay to work properly
            var that = this;
            setTimeout(function() {
                window.URL.revokeObjectURL(that.href);
            }, 1500);
        };

        dlink.click();
        dlink.remove();
    }
    </script>
</body>
</html>

Я создал это, адаптировав код из этой демонстрации HTML5 и возясь с до тех пор, пока оно не сработало, поэтому я уверен, что с ним есть проблемы (прокомментируйте или отредактируйте, если у вас есть улучшения!), но это рабочее решение для одного щелчка мыши.

(по крайней мере, у меня это работает на последней версии Chrome в Windows 7)

person ahuff44    schedule 07.02.2016
comment
Потрясающе ... награда будет вручена через 23 часа 55 минут ... - person CL22; 01.08.2016
comment
Это должен быть принятый ответ. Он показывает «тяжелую» работу по созданию URI данных. Не просто сказать, что вам нужно их использовать. - person pseudosavant; 02.08.2016
comment
Для Firefox вам понадобится document.body.appendChild (dlink) после вызова createElement (), а затем, предположительно, document.body.removeChild (dlink) после dlink.remove (). - person Alexander Pruss; 18.04.2017
comment
Протестирован Firefox: требуется document.body.appendChild (dlink), но не нужно removeChild, достаточно remove (). Спасибо, ahuff & alexander! - person Eta; 07.02.2018
comment
только что проверил Chrome версии 73.0.3683.103 (официальная сборка) (64-разрядная версия), РАБОТАЕТ! - person Mehar Charan Sahai; 19.04.2019
comment
Чтобы избежать var that = this; . - person nice_dev; 24.07.2019
comment
Я считаю, что браузеры не будут соблюдать атрибут загрузки, если файл является PDF-файлом, и вместо этого будут делать то, что настройки браузера говорят, что они будут делать для PDF-файлов, это верно, по крайней мере, для chrome. - person Charles L.; 31.03.2021

PDF-файл? Нет. txt файл. да. С недавними blob URI HTML5. Самая простая форма вашего кода будет выглядеть примерно так:

window.URL = window.webkitURL || window.URL;
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
var file = new window.BlobBuilder(),
    number = Math.random().toString(); //In the append method next, it has to be a string
file.append(number); //Your random number is put in the file

var a = document.createElement('a');
a.href = window.URL.createObjectURL(file.getBlob('text/plain'));
a.download = 'filename.txt';
a.textContent = 'Download file!';
document.body.appendChild(a);

Возможно, вы можете использовать другие методы, упомянутые в других ответах, в качестве запасного варианта, поскольку BlobBuilder, вероятно, не поддерживается очень хорошо.

Демо

Примечание. BlobBuilder, похоже, устарел. Чтобы узнать, как использовать Blob вместо BlobBuilder. Спасибо @limonte за внимание.

person Some Guy    schedule 29.11.2011
comment
BlobBuilder устарел, см. stackoverflow.com/a/15031019/1331425 - person Limon Monte; 18.10.2015
comment
@limonte Спасибо! Отредактировал это в ответ - person Some Guy; 18.10.2015