Использование HTML5 / Javascript для создания и сохранения файла


Я играл с WebGL в последнее время, и получил Collada reader работает. Проблема в том, что это довольно медленно (Collada-очень подробный формат), поэтому я собираюсь начать конвертировать файлы в более простой в использовании формат (возможно, JSON). Дело в том, что у меня уже есть код для разбора файла в Javascript, поэтому я могу также использовать его в качестве своего экспортера! Проблема в экономии.

теперь я знаю, что могу разобрать файл, отправить результат на сервер и попросить браузер запросить файл обратно с сервера в качестве загрузки. Но на самом деле сервер не имеет никакого отношения к этому конкретному процессу, так зачем его вовлекать? У меня уже есть содержимое нужного файла в памяти. Есть ли способ, которым я мог бы представить пользователю загрузку с использованием чистого javascript? (Я сомневаюсь в этом, но могу также спросить...)

и для ясности: я не пытаюсь получить доступ к файловой системе без ведома пользователя! Пользователь предоставит файл (возможно, с помощью перетаскивания), скрипт будет преобразовать файл в памяти, и пользователю будет предложено скачать результат. Все из которых должны быть "безопасными" действиями, насколько это касается браузера.

[EDIT]: Я не упоминал об этом заранее, поэтому плакаты, которые ответили "Flash", достаточно действительны, но часть того, что я делаю, - это попытка подчеркнуть, что можно сделать с помощью чистого HTML5... так что вспышка прямо в моем случае. (Хотя это совершенно правильный ответ для тех, кто делает "настоящий" веб-приложение.) То есть похоже, мне не повезло, если я не хочу привлекать сервер. Все равно спасибо!

14 276

14 ответов:

хорошо, создание данных: URI определенно делает трюк для меня, благодаря Мэтью и Деннкстеру, указывающим на этот вариант! Вот в основном, как я это делаю:

1) получить все содержимое в строку под названием "контент" (например, создав его там изначально или прочитав innerHTML тега уже построенной страницы).

2) Построить URI данных:

uriContent = "data:application/octet-stream," + encodeURIComponent(content);

будут существовать ограничения длины в зависимости от типа браузера и т. д., но, например, Firefox 3.6.12 работает до тех пор, пока не менее 256к. Кодирование в base64, а не с помощью encodeURIComponent может сделать вещи более эффективными, но для меня это было нормально.

3) откройте новое окно и "перенаправьте" его на этот URI запрашивает местоположение загрузки моей сгенерированной страницы JavaScript:

newWindow = window.open(uriContent, 'neuesDokument');

вот именно.

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

function download(filename, text) {
    var pom = document.createElement('a');
    pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
    pom.setAttribute('download', filename);

    if (document.createEvent) {
        var event = document.createEvent('MouseEvents');
        event.initEvent('click', true, true);
        pom.dispatchEvent(event);
    }
    else {
        pom.click();
    }
}

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

download('test.txt', 'Hello world!');

HTML5 определил a window.saveAs(blob, filename) метод. Он не поддерживается ни одним браузером прямо сейчас. Но есть библиотека совместимости под названием Сохранитель файлов.js что добавляет эту функцию в большинстве современных браузеров (включая Internet Explorer 10+). Internet Explorer 10 поддерживает navigator.msSaveBlob(blob, filename) метод ( MSDN), который используется в FileSaver.js для поддержки Internet Explorer.

Я написал блоге С более подробной информацией об этой проблеме.

сохранение больших файлов

длинные URI данных могут дать проблемы с производительностью в браузерах. Другой вариант сохранения созданных на стороне клиента файлов-поместить их содержимое в объект Blob (или File) и создать ссылку для загрузки с помощью URL.createObjectURL(blob). Это возвращает URL-адрес, который можно использовать для извлечения содержимого большого двоичного объекта. Blob хранится внутри браузера до тех пор, пока либо URL.revokeObjectURL() вызывается по URL-адресу или документ, который его создал, закрыт. Большинство веб-браузеров поддержка URL-адресов объектов, Opera Mini является единственным, который не поддерживает их.

принудительная загрузка

если данные являются текстом или изображением, браузер может открыть файл, а не сохранять его на диск. Чтобы заставить файл быть загруженным после нажатия на ссылку, вы можете использовать. Однако, не все веб-браузеры имеют поддержка атрибута загрузки. Другой вариант-использовать application/octet-stream как mime-тип файла, но это приводит к тому, что файл представляется в виде двоичного большого двоичного объекта, который особенно недружественен Пользователю, если вы не можете или не можете указать имя файла. Смотрите также ' принудительно открыть " Сохранить как..."всплывающее окно открыть по текстовой ссылке нажмите для pdf в HTML'.

указание имени

если blob создается с помощью конструктора файлов, вы также можете установить имя файла, но только несколько веб-браузеров (включая Chrome и Firefox) имеют поддержка конструктора файлов. Имя файла также может быть указан в качестве аргумента download атрибут, но это зависит от тонны соображений безопасности. Internet Explorer 10 и 11 предоставляет свой собственный метод,msSaveBlob, чтобы указать имя файла.

пример кода

var file;
var data = [];
data.push("This is a test\n");
data.push("Of creating a file\n");
data.push("In a browser\n");
var properties = {type: 'text/plain'}; // Specify the file's mime-type.
try {
  // Specify the filename using the File constructor, but ...
  file = new File(data, "file.txt", properties);
} catch (e) {
  // ... fall back to the Blob constructor if that isn't supported.
  file = new Blob(data, properties);
}
var url = URL.createObjectURL(file);
document.getElementById('link').href = url;
<a id="link" target="_blank" download="file.txt">Download</a>
function download(content, filename, contentType)
{
    if(!contentType) contentType = 'application/octet-stream';
        var a = document.createElement('a');
        var blob = new Blob([content], {'type':contentType});
        a.href = window.URL.createObjectURL(blob);
        a.download = filename;
        a.click();
}

взгляните на Дуга найнера Downloadify который является Флэш-интерфейс JavaScript, чтобы сделать это.

Downloadify-это крошечная библиотека JavaScript + Flash, которая позволяет создавать и сохранять файлы на лету, в браузере, без взаимодействия с сервером.

Простое Решение!

<a download="My-FileName.txt" href="data:application/octet-stream,HELLO-WORLDDDDDDDD">Click here</a>    

работает во всех современных браузерах (см. демо).

п.С. href также можно установить с помощью Javascript:
'data:application/octet-stream,' + encodeURIComponent(content);

вы можете создать URI данных. Однако существуют определенные для браузера ограничения.

я использовал FileSaver (https://github.com/eligrey/FileSaver.js) и это работает просто отлично.
Например, я сделал эту функцию для экспорта журналов, отображаемых на странице.
Вы должны передать массив для экземпляра Blob, поэтому я просто, возможно, не написал это правильно, но это работает для меня.
На всякий случай, будьте осторожны с заменой: это синтаксис, чтобы сделать это глобальным, иначе он заменит только первый, который он встречает.

exportLogs : function(){
    var array = new Array();

    var str = $('#logs').html();
    array[0] = str.replace(/<br>/g, '\n\t');

    var blob = new Blob(array, {type: "text/plain;charset=utf-8"});
    saveAs(blob, "example.log");
}

я нашел два простых подходов, которые работают для меня. Во-первых, используя уже нажал a элемент и ввод данных загрузки. И во-вторых, генерируя a элемент с данными загрузки, выполняющий a.click() и удалить его снова. Но второй подход работает только в том случае, если вызывается действие щелчка пользователя. (Некоторые) блок браузера click() из других контекстов, таких как при загрузке или срабатывает после таймаута (setTimeout).

<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <script type="text/javascript">
      function linkDownload(a, filename, content) {
        contentType =  'data:application/octet-stream,';
        uriContent = contentType + encodeURIComponent(content);
        a.setAttribute('href', uriContent);
        a.setAttribute('download', filename);
      }
      function download(filename, content) {
        var a = document.createElement('a');
        linkDownload(a, filename, content);
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
      }
    </script>
   </head>
  <body>
    <a href="#" onclick="linkDownload(this, 'test.txt', 'Hello World!');">download</a>
    <button onclick="download('test.txt', 'Hello World!');">download</button>
  </body>
</html>

вот ссылка на метод URI данных, предложенный Мэтью, он работал на safari, но не очень хорошо, потому что я не мог установить тип файла, он сохраняется как "неизвестный", а затем мне нужно снова пойти туда позже и изменить его, чтобы просмотреть файл...

http://www.nihilogic.dk/labs/canvas2image/

вы можете использовать localStorage. Это Html5 эквивалент cookies. Он, кажется, работает на Chrome и Firefox, но на Firefox, мне нужно было загрузить его на сервер. То есть тестирование непосредственно на моем домашнем компьютере не сработало.

Я работаю над примерами HTML5. Перейти к http://faculty.purchase.edu/jeanine.meyer/html5/html5explain.html и прокрутите до лабиринта один. Информация для повторного построения лабиринта хранится с помощью localStorage.

Я пришел к этой статье ищу HTML5 JavaScript для загрузки и работы с xml файлами. Это то же самое, что и старые html и JavaScript????

Как уже упоминалось ранее File API, вместе с FileWriter и файловой системы API можно использовать для хранения файлов на компьютере клиента из контекста вкладки/окна браузера.

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

  • реализации API в настоящее время существуют только в браузерах на базе Chromium (Chrome & Opera)
  • оба API были сняты с трека стандартов W3C 24 апреля 2014 года, и на данный момент являются собственностью
  • удаление (Теперь проприетарных) API из реализации браузеров в будущем-это возможность
  • A песочница (расположение на диске, вне которого файлы не могут производить никакого эффекта) используется для хранения файлов, созданных с помощью API
  • A виртуальная файловая система (структура каталогов, которая не обязательно существует на диске в та же форма, что и при доступе из браузера) используется для представления файлов, созданных с помощью API

вот простые примеры того, как API используются, прямо и косвенно, в тандеме, чтобы сделать это:

хлебобулочные изделия*

bakedGoods.get({
        data: ["testFile"],
        storageTypes: ["fileSystem"],
        options: {fileSystem:{storageType: Window.PERSISTENT}},
        complete: function(resultDataObj, byStorageTypeErrorObj){}
});

использование raw-файлов, FileWriter и API файловой системы

function onQuotaRequestSuccess(grantedQuota)
{

    function saveFile(directoryEntry)
    {

        function createFileWriter(fileEntry)
        {

            function write(fileWriter)
            {
                var dataBlob = new Blob(["Hello world!"], {type: "text/plain"});
                fileWriter.write(dataBlob);              
            }

            fileEntry.createWriter(write);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: true, exclusive: true},
            createFileWriter
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, saveFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

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

  • возобновленный интерес со стороны поставщиков браузеров ООН может вернуть их обратно на него
  • проникновение на рынок реализации (на основе хрома) браузеры высокие
  • Google (основной вклад в Chromium) не дал и дату окончания срока службы API

если "некоторые случаи" охватывает свой собственный, однако, для вас, чтобы решать.

*BakedGoods поддерживается не кем иным, как этим парнем прямо здесь:)

вот учебник для экспорта файлов в формате ZIP:

перед началом работы есть библиотека для сохранения файлов, имя библиотеки-fileSaver.js, вы можете найти эту библиотеку здесь. Давайте начнем, теперь, включите необходимые библиотеки:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.4/jszip.min.js"  type="text/javascript"></script>
<script type="text/javascript" src="https://fastcdn.org/FileSaver.js/1.1.20151003/FileSaver.js" ></script>

теперь скопируйте этот код, и этот код загрузит zip-файл с файлом hello.тхт с содержанием "Привет, Мир". Если все работает нормально, это скачать файл.

<script type="text/javascript">
    var zip = new JSZip();
    zip.file("Hello.txt", "Hello World\n");
    zip.generateAsync({type:"blob"})
    .then(function(content) {
        // see FileSaver.js
        saveAs(content, "file.zip");
    });
</script>

это позволит загрузить a файл.застежка-молния. Вы можете прочитать больше здесь: http://www.wapgee.com/story/248/guide-to-create-zip-files-using-javascript-by-using-jszip-library