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

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

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

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

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

14 ответов


OK, создание данных: 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 определен window.saveAs(blob, filename) метод. Сейчас он не поддерживается ни одним браузером. Но есть библиотека совместимости под названием FileSaver.js это добавляет эту функцию в большинство современных браузеров (включая Internet Explorer 10+). Internet Explorer 10 поддерживает navigator.msSaveBlob(blob, filename) метод (MSDN), который используется в FileSaver.js для поддержки Internet Explorer.

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


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

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

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

если данные текст или изображение, браузер может открыть файл, вместо сохранения его на диск. Чтобы вызвать загрузку файла при нажатии на ссылку, вы можете использовать . Однако, не все веб-браузеры имеют поддержка атрибута загрузки. Другой вариант-использовать application/octet-stream как mime-тип файла, но это приводит к тому, что файл представляется как двоичный blob, который особенно недружелюбен Пользователю, если вы не можете указать имя файла. См. также ' Force, чтобы открыть " Сохранить как..."всплывающее окно открыто по текстовой ссылке нажмите для 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 на основе Flash для этого.

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????


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

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

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

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

BakedGoods*

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

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

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>

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