Создайте файл в памяти для загрузки пользователем, а не через сервер

Можно ли как-нибудь создать текстовый файл на стороне клиента и предложить пользователю загрузить его без какого-либо взаимодействия с сервером? Я знаю, что не могу писать напрямую на их машину (безопасность и все), но могу ли я создать и предложить им сохранить ее?

вопрос задан 8.09.2010
Joseph Silber
148346 репутация

16 ответов


  • 550 рейтинг

    Простое решение для готовых браузеров HTML5. , ,

    function download(filename, text) {
      var element = document.createElement('a');
      element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
      element.setAttribute('download', filename);
    
      element.style.display = 'none';
      document.body.appendChild(element);
    
      element.click();
    
      document.body.removeChild(element);
    }
    form * {
      display: block;
      margin: 10px;
    }
    
    
     

    Использование

    download('test.txt', 'Hello world!');
    
    ответ дан Matěj Pokorný, с репутацией 9206, 12.08.2013
  • 364 рейтинг

    Вы можете использовать URI данных. Поддержка браузера варьируется; см. Википедия . Пример:

    text file
    

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

    Для CSV, вы можете использовать:

    CSV Octet
    

    Попробуйте демо jsFiddle .

    ответ дан Matthew Flaschen, с репутацией 213715, 8.09.2010
  • 155 рейтинг

    Все вышеприведенные примеры прекрасно работают в Chrome и IE, но не работают в Firefox. Пожалуйста, рассмотрите добавление якоря к телу и удаление его после щелчка.

    var a = window.document.createElement('a');
    a.href = window.URL.createObjectURL(new Blob(['Test,Text'], {type: 'text/csv'}));
    a.download = 'test.csv';
    
    // Append anchor to body.
    document.body.appendChild(a);
    a.click();
    
    // Remove anchor from body
    document.body.removeChild(a);
    
    ответ дан naren, с репутацией 8869, 25.11.2013
  • 144 рейтинг

    Все вышеперечисленные решения работают не во всех браузерах. Вот что в конечном итоге работает в IE 10+, Firefox и Chrome (и без jQuery или любой другой библиотеки):

    save: function(filename, data) {
        var blob = new Blob([data], {type: 'text/csv'});
        if(window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveBlob(blob, filename);
        }
        else{
            var elem = window.document.createElement('a');
            elem.href = window.URL.createObjectURL(blob);
            elem.download = filename;        
            document.body.appendChild(elem);
            elem.click();        
            document.body.removeChild(elem);
        }
    }
    

    Обратите внимание, что в зависимости от вашей ситуации вы также можете позвонить по номеру . revokeObjectURL после удаления elem. Согласно документам для URL. createObjectURL :

    Каждый раз, когда вы вызываете createObjectURL (), создается новый URL-адрес объекта, даже если вы уже создали его для того же объекта. Каждый из них должен быть освобожден путем вызова URL. revokeObjectURL (), когда они вам больше не нужны. Браузеры выпустят их автоматически, когда документ выгружен; однако для оптимальной производительности и использования памяти, если есть безопасные времена, когда вы можете явно выгружать их, вы должны сделать это.

    ответ дан Ludovic Feltz, с репутацией 6820, 5.11.2015
  • 101 рейтинг

    Я с удовольствием использую FileSaver. JS . Его совместимость довольно хорошая (IE10 + и все остальное), и он очень прост в использовании:

    var blob = new Blob(["some text"], {
        type: "text/plain;charset=utf-8;",
    });
    saveAs(blob, "thing.txt");
    
    ответ дан Daniel Buckmaster, с репутацией 4344, 8.05.2013
  • 19 рейтинг

    Следующий метод работает в IE11 +, Firefox 25+ и Chrome 30+:

    export
    
    

    См. Это в действии: http: // jsfiddle. net / Kg7eA /

    Firefox и Chrome поддерживают URI данных для навигации, что позволяет нам создавать файлы путем перехода к URI данных, в то время как IE не поддерживает его в целях безопасности.

    С другой стороны, в IE есть API для сохранения большого двоичного объекта, который можно использовать для создания и загрузки файлов.

    ответ дан dinesh ygv, с репутацией 1270, 27.12.2013
  • 8 рейтинг

    Если вы просто хотите преобразовать строку, которая будет доступна для загрузки, вы можете попробовать это с помощью jQuery.

    $('a.download').attr('href', 'data:application/csv;charset=utf-8,' + encodeURI(data));
    
    ответ дан Rick, с репутацией 5289, 2.02.2015
  • 8 рейтинг

    Это решение извлечено непосредственно из tiddlywiki's (tiddlywiki. com) хранилище github. Я использовал Tiddlywiki почти во всех браузерах, и это работает как шарм:

    function(filename,text){
        // Set up the link
        var link = document.createElement("a");
        link.setAttribute("target","_blank");
        if(Blob !== undefined) {
            var blob = new Blob([text], {type: "text/plain"});
            link.setAttribute("href", URL.createObjectURL(blob));
        } else {
            link.setAttribute("href","data:text/plain," + encodeURIComponent(text));
        }
        link.setAttribute("download",filename);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }
    

    Github репо: Скачать модуль заставки

    ответ дан Danielo515, с репутацией 950, 15.07.2015
  • 8 рейтинг

    Решение, которое работает на IE10: (Мне нужен CSV-файл, но достаточно изменить тип и имя файла на TXT)

    var csvContent=data; //here we load our csv data 
    var blob = new Blob([csvContent],{
        type: "text/csv;charset=utf-8;"
    });
    
    navigator.msSaveBlob(blob, "filename.csv")
    
    ответ дан Dzarek, с репутацией 406, 8.11.2013
  • 5 рейтинг
    var element = document.createElement('a');
    element.setAttribute('href', 'data:text/text;charset=utf-8,' +      encodeURI(data));
    element.setAttribute('download', "fileName.txt");
    element.click();
    
    ответ дан MANVENDRA LODHI, с репутацией 59, 9.05.2015
  • 4 рейтинг

    Как упоминалось ранее, filesaver - отличный пакет для работы с файлами на стороне клиента. Но это не очень хорошо с большими файлами. StreamSaver. JS является альтернативным решением (которое указано в FileServer. JS), который может обрабатывать большие файлы:

    const fileStream = streamSaver.createWriteStream('filename.txt', size);
    const writer = fileStream.getWriter();
    for(var i = 0; i < 100; i++){
        var uint8array = new TextEncoder("utf-8").encode("Plain Text");
        writer.write(uint8array);
    }
    writer.close()
    
    ответ дан مصطفی, с репутацией 536, 17.05.2017
  • 4 рейтинг

    По состоянию на апрель 2014 года API-интерфейсы FileSystem могут быть не стандартизированы в W3C. Думаю, любой, кто смотрит на решение с помощью blob, должен быть осторожен.

    HTML5 качает головой

    Список рассылки W3C в FileSytem API

    ответ дан pravin, с репутацией 591, 20.01.2015
  • 4 рейтинг

    На основе ответа @Rick, который был действительно полезен.

    Вы должны указать строку data, если хотите поделиться ей следующим образом:

    $('a.download').attr('href', 'data:application/csv;charset=utf-8,'+ encodeURI(data));
    

    ` Извините, я не могу комментировать ответ @ Rick из-за моей низкой репутации в StackOverflow.

    Предложение о редактировании было передано и отклонено.

    ответ дан atfornes, с репутацией 308, 7.09.2015
  • 3 рейтинг

    Вы даже можете сделать один лучше, чем просто URI - используя Chrome, вы также можете предложить имя файла, как описано в этом сообщении в блоге о присвоении имени загрузке при использовании URI .

    ответ дан owencm, с репутацией 4141, 6.04.2013
  • -19 рейтинг

    Если файл содержит текстовые данные, я использую технику, чтобы поместить текст в элемент textarea и сделать так, чтобы пользователь выделил его (щелкните в textarea, затем ctrl-A), а затем скопируйте, а затем вставьте в текстовый редактор.

    ответ дан HBP, с репутацией 11981, 8.09.2010
  • -30 рейтинг

    Это действительно возможно - используйте Flash.

    Вы можете либо сгенерировать контент с помощью JS, а затем инициализировать некоторые флэш-переменные, либо просто сделать все внутри флэш-фильма.

    Пожалуйста, посмотрите на это для некоторых важных замечаний.

    ответ дан Mr.RoyDiibs, с репутацией 66, 8.09.2010