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



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

589   16  

16 ответов:

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

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

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

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

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

попробовать демо jsFiddle.

простое решение для 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!');

все вышеприведенные примеры отлично работают в 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);

все вышеперечисленные решения не работали во всех браузерах. Вот что, наконец, работает на 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 (), когда они вам больше не нужны. Браузеры будут освобождать их автоматически при выгрузке документа; однако для оптимальной производительности и использования памяти, если есть безопасные времена, когда вы можете явно выгрузить их, вы должны сделать это.

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

var blob = new Blob(["some text"], {
    type: "text/plain;charset=utf-8;",
});
saveAs(blob, "thing.txt");

следующий метод работает в 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 для сохранения большого двоичного объекта, который может быть использован для создания и загрузки файлов.

решение, которое работает на 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")

это решение извлекается непосредственно из tiddlywiki (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 РЕПО: скачать saver модуль

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

$('a.download').attr('href', 'data:application/csv;charset=utf-8,' + encodeURI(data));
var element = document.createElement('a');
element.setAttribute('href', 'data:text/text;charset=utf-8,' +      encodeURI(data));
element.setAttribute('download', "fileName.txt");
element.click();

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

HTML5 rocks heads up

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

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

вы должны scape строку data Если вы хотите поделиться это так:

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

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

An изменить предложение был разделен и отклонен.

Как упоминалось ранее, filesaver - отличный пакет для работы с файлами на клиентской стороне. Но, это не очень хорошо с большими файлами. StreamSaver.js является альтернативным решением (которое указано в файловом сервере.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()

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

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

Это на самом деле возможно - используйте вспышку.

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

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

Comments

    Ничего не найдено.