Korzystanie z HTML5 / Javascript do generowania i zapisywania pliku

Ostatnio bawiłem się w WebGL i uruchomiłem Czytnik Collada. Problem polega na tym, że jest dość powolny (Collada jest bardzo szczegółowy format), więc mam zamiar rozpocząć konwertowanie plików do łatwiejszego w użyciu formatu (prawdopodobnie JSON). Rzecz w tym, że mam już kod do analizy pliku w Javascript, więc równie dobrze mogę go używać jako mojego eksportera! Problemem jest oszczędzanie.

Teraz wiem, że mogę przeanalizować plik, wysłać wynik na serwer, a przeglądarka zażąda pliku z powrotem serwer jako download. Ale w rzeczywistości serwer nie ma nic wspólnego z tym konkretnym procesem, więc po co go angażować? Mam już zawartość żądanego pliku w pamięci. Czy jest jakiś sposób, aby przedstawić użytkownikowi pobieranie za pomocą czystego javascript? (Wątpię, ale równie dobrze mogę zapytać...)

I żeby było jasne: nie próbuję uzyskać dostępu do systemu plików bez wiedzy użytkowników! Użytkownik dostarczy plik (prawdopodobnie poprzez przeciąganie i upuszczanie), skrypt przekształci plik w pamięci, a użytkownik zostanie poproszony o pobranie wyniku. Wszystkie z nich powinny być "bezpieczne" działania, jeśli chodzi o przeglądarkę.

[EDIT]: nie wspomniałem o tym z góry, więc plakaty z odpowiedzią "Flash" są wystarczająco ważne, ale częścią tego, co robię, jest próba podkreślenia tego, co można zrobić z czystym HTML5... więc Flash jest w moim przypadku. (Chociaż jest to całkowicie poprawna odpowiedź dla każdego, kto robi "prawdziwą" aplikację internetową.) W tym przypadku wygląda na to, że odpadam powodzenia, chyba że chcę zaangażować serwer. I tak dzięki!

Author: Toji, 2010-05-24

14 answers

Ok, tworzenie danych:URI zdecydowanie robi sztuczkę dla mnie, dzięki Matthew i Dennkster wskazując tę opcję! Oto w zasadzie jak to robię:

1) Uzyskaj całą zawartość w łańcuchu o nazwie "content" (np. tworząc ją tam początkowo lub czytając innerHTML znacznika już zbudowanej strony).

2) Zbuduj Uri danych:

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

Będą ograniczenia długości w zależności od typu przeglądarki itp., ale np. Firefox 3.6.12 działa do co najmniej 256k. kodowanie w Base64 zamiast tego przy użyciu encodeURIComponent może uczynić rzeczy bardziej wydajne, ale dla mnie to było ok.

3) Otwórz nowe okno i "przekieruj" je do tego URI prosi o lokalizację pobierania mojej strony generowanej przez JavaScript:

newWindow = window.open(uriContent, 'neuesDokument');
To wszystko.
 236
Author: Nøk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-28 15:00:53

Proste rozwiązanie dla przeglądarek gotowych do 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();
    }
}

Użycie

download('test.txt', 'Hello world!');
 247
Author: Matěj Pokorný,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-16 11:44:32

HTML5 zdefiniował metodę window.saveAs(blob, filename). Nie jest teraz obsługiwany przez żadną przeglądarkę. Istnieje jednak biblioteka kompatybilności o nazwie FileSaver.js , który dodaje tę funkcję do większości nowoczesnych przeglądarek (w tym Internet Explorer 10+). Internet Explorer 10 obsługuje metodę navigator.msSaveBlob(blob, filename) ( MSDN ), która jest używana w przeglądarce plików.js dla obsługi Internet Explorera.

Napisałem blog post z więcej szczegółów na temat tego problemu.

 76
Author: panzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-24 17:22:45

Zapisywanie dużych plików

Długie Uri danych mogą powodować problemy z wydajnością w przeglądarkach. Inną opcją zapisywania wygenerowanych po stronie klienta plików, jest umieszczenie ich zawartości w obiekcie Blob (lub Pliku) i utworzenie łącza pobierania za pomocą URL.createObjectURL(blob). Zwraca adres URL, który może być użyty do pobrania zawartości obiektu blob. Obiekt blob jest przechowywany w przeglądarce do momentu wywołania URL.revokeObjectURL() w adresie URL lub zamknięcia dokumentu, który go utworzył. Większość przeglądarek posiada wsparcie dla obiektu Adresy URL , Opera Mini jest jedyną, która ich nie obsługuje.

Wymuszanie pobierania

Jeśli dane są tekstem lub obrazem, przeglądarka może otworzyć plik, zamiast zapisać go na dysku. Aby spowodować pobranie pliku po kliknięciu linku, możesz użyć atrybutu download. Jednak nie wszystkie przeglądarki internetowe mają wsparcie dla atrybutu download. Inną opcją jest użycie application/octet-stream jako typu MIME pliku, ale powoduje to, że plik będzie prezentowany jako binarny obiekt blob co jest szczególnie nieprzyjazne dla użytkownika, jeśli nie możesz lub nie możesz podać nazwy pliku. Zobacz także 'wymuszenie otwarcia " Zapisz jako..."popup open at text link click for pdf in HTML ".

Określanie nazwy pliku

Jeśli obiekt blob jest tworzony za pomocą konstruktora plików, możesz również ustawić nazwę pliku, ale tylko kilka przeglądarek internetowych (w tym Chrome i Firefox) ma wsparcie dla konstruktora Plików. Nazwę pliku można również podać jako argument atrybutu download, ale jest to z zastrzeżeniem ton względów bezpieczeństwa . Internet Explorer 10 i 11 udostępnia własną metodę, msSaveBlob, aby określić nazwę pliku.

Przykładowy kod

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>
 34
Author: bcmpinc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-07 14:10:48
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();
}
 32
Author: Yassir Ennazk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-07 17:03:17

Spójrz na Downloadify, który jest interfejsem JavaScript opartym na Flashu.

Downloadify jest małą biblioteką JavaScript + Flash, która umożliwia generowanie i zapisywanie plików w locie, w przeglądarce, bez interakcji z serwerem.

 26
Author: Pekka 웃,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-27 15:04:08

Proste Rozwiązanie!

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

Działa we wszystkich nowoczesnych przeglądarkach (Zobacz DEMO).

P. s. href można też ustawić za pomocą Javascript:
'data:application/octet-stream,' + encodeURIComponent(content);

 14
Author: T.Todua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-15 19:02:11

Możesz wygenerować data URI. Istnieją jednak ograniczenia specyficzne dla przeglądarki.

 10
Author: Matthew Flaschen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-24 14:22:46

Użyłem FileSaver ( https://github.com/eligrey/FileSaver.js ) i działa dobrze.
Na przykład, zrobiłem tę funkcję, aby wyeksportować dzienniki wyświetlane na stronie.
Musisz podać tablicę do instancjacji Bloba, więc może nie napisałem tego dobrze, ale dla mnie działa.
Na wszelki wypadek, bądź ostrożny z replace: to jest składnia, aby uczynić ten globalny, w przeciwnym razie zastąpi tylko pierwszą, którą spotyka.

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");
}
 9
Author: Razakhel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-10 12:56:01

Znalazłem dwa proste podejścia, które działają dla mnie. Najpierw użyj już klikniętego elementu a i wstrzyknij dane pobierania. Po drugie, wygenerowanie elementu a z danymi pobierania, wykonanie a.click() i ponowne usunięcie go. Ale drugie podejście działa tylko wtedy, gdy jest wywoływane przez akcję kliknięcia użytkownika. (Niektóre) blokowanie przeglądarki click() z innych kontekstów, takich jak podczas ładowania lub wyzwalane po przekroczeniu limitu czasu (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>
 8
Author: maikel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-22 10:26:02

Oto link do metody data URI, która Mathew zasugerował, działała na safari, ale nie za dobrze, ponieważ nie mogłem ustawić typu pliku, zostaje zapisany jako "Nieznany", a następnie muszę tam wrócić później I zmienić go, aby wyświetlić plik...

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

 6
Author: Dennkster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-14 14:41:18

Możesz użyć localStorage. Jest to odpowiednik plików cookie Html5. Wygląda na to, że działa na Chrome i Firefoksie, ale na Firefoksie musiałem przesłać go na serwer. Oznacza to, że testowanie bezpośrednio na moim komputerze domowym nie działało.

Pracuję nad przykładami HTML5. Przejdź do http://faculty.purchase.edu/jeanine.meyer/html5/html5explain.html i przewiń do pierwszego labiryntu. Informacje do ponownego zbudowania labiryntu są przechowywane za pomocą localStorage.

Przyszedłem do tego artykułu szukając HTML5 JavaScript do ładowania i pracy z plikami xml. Czy jest taki sam jak starszy html i JavaScript????

 4
Author: Jeanine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-01 19:03:37

Jak wcześniej wspomniano, API File wraz z API FileWriter i FileSystem mogą być używane do przechowywania plików na komputerze klienta z kontekstu karty/okna przeglądarki.

Jest jednak kilka rzeczy odnoszących się do dwóch ostatnich interfejsów API, o których powinieneś wiedzieć:

    W przeciwieństwie do większości przeglądarek opartych na Chromium (Chrome i Opera), API są obecnie dostępne tylko w przeglądarkach opartych na Chromium.]}
  • oba interfejsy API zostały wyłączone ze standardów W3C tor na 24 kwietnia 2014 roku i od teraz są zastrzeżone
  • [13]}usunięcie (obecnie zastrzeżonych) API z implementacji przeglądarek w przyszłości jest możliwością Do przechowywania plików utworzonych za pomocą interfejsów API
  • a sandbox (lokalizacja na dysku, poza którym pliki nie mogą wywoływać żadnego efektu) służy]}
  • a wirtualny system plików (struktura katalogów, która nie musi istnieć na dysku w takiej samej formie, jak w przypadku dostępu z poziomu przeglądarki) jest używane reprezentują pliki utworzone za pomocą API
Aby to zrobić, należy wykonać następujące czynności:]}

BakedGoods*

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

Używanie plików raw, FileWriter i interfejsów API systemu plików

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);

Chociaż system plików i API FileWriter nie są już na ścieżce standardów, ich użycie może być uzasadnione w niektórych przypadkach, moim zdaniem, ponieważ:

  • nie-implementujący dostawcy przeglądarek mogą umieścić je z powrotem na niej
  • penetracja rynku implementujących (opartych na Chromium) przeglądarek jest wysoka
  • Google (główny współtwórca Chromium) nie podało daty końca życia interfejsów API.]}
To, czy "niektóre sprawy" obejmują Twoje własne, należy jednak do ciebie.

*BakedGoods jest utrzymywany przez nikogo innego jak ten facet tutaj :)

 3
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-07 21:24:56

Oto samouczek eksportowania plików jako ZIP:

Przed rozpoczęciem, istnieje biblioteka do zapisywania plików, nazwa biblioteki to fileSaver.js, tę bibliotekę znajdziesz tutaj. Zacznijmy od dołączenia wymaganych bibliotek:

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

Teraz skopiuj ten kod, a ten kod pobierze plik zip z plikiem hello.txt o treści Hello World. Jeśli wszystko działa dobrze, to pobierze plik.

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

Spowoduje to pobranie pliku o nazwie file.zip. Możesz Czytaj więcej tutaj: http://www.wapgee.com/story/248/guide-to-create-zip-files-using-javascript-by-using-jszip-library

 0
Author: Ilyas karim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-30 09:46:41