Как создать файл в памяти для загрузки пользователем, но не через сервер? - PullRequest
743 голосов
/ 08 сентября 2010

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

Ответы [ 19 ]

650 голосов
/ 13 августа 2013

Простое решение для браузеров с поддержкой 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;
}
<form onsubmit="download(this['name'].value, this['text'].value)">
  <input type="text" name="name" value="test.txt">
  <textarea name="text"></textarea>
  <input type="submit" value="Download">
</form>

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

download('test.txt', 'Hello world!');
400 голосов
/ 08 сентября 2010

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

<a href="data:application/octet-stream;charset=utf-16le;base64,//5mAG8AbwAgAGIAYQByAAoA">text file</a>

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

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

<a href="data:application/octet-stream,field1%2Cfield2%0Afoo%2Cbar%0Agoo%2Cgai%0A">CSV Octet</a>

Попробуйте демоверсию jsFiddle .

186 голосов
/ 05 ноября 2015

Все вышеперечисленные решения работают не во всех браузерах.Вот что в конечном итоге работает в 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);
    }
}

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

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

174 голосов
/ 25 ноября 2013

Все приведенные выше примеры прекрасно работают в 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);
108 голосов
/ 09 мая 2013

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

var blob = new Blob(["some text"], {
    type: "text/plain;charset=utf-8;",
});
saveAs(blob, "thing.txt");
22 голосов
/ 27 декабря 2013

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

<a id="export" class="myButton" download="" href="#">export</a>
<script>
    function createDownloadLink(anchorSelector, str, fileName){
        if(window.navigator.msSaveOrOpenBlob) {
            var fileData = [str];
            blobObject = new Blob(fileData);
            $(anchorSelector).click(function(){
                window.navigator.msSaveOrOpenBlob(blobObject, fileName);
            });
        } else {
            var url = "data:text/plain;charset=utf-8," + encodeURIComponent(str);
            $(anchorSelector).attr("download", fileName);               
            $(anchorSelector).attr("href", url);
        }
    }

    $(function () {
        var str = "hi,file";
        createDownloadLink("#export",str,"file.txt");
    });

</script>

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

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

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

12 голосов
/ 15 июля 2015

Это решение извлечено непосредственно из репозитория github tiddlywiki (tiddlywiki.com). Я использовал 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 репо: Скачать модуль заставки

10 голосов
/ 08 ноября 2013

Решение, которое работает на 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")
9 голосов
/ 02 февраля 2015

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

$('a.download').attr('href', 'data:application/csv;charset=utf-8,' + encodeURI(data));
7 голосов
/ 09 мая 2015
var element = document.createElement('a');
element.setAttribute('href', 'data:text/text;charset=utf-8,' +      encodeURI(data));
element.setAttribute('download', "fileName.txt");
element.click();
...