webentwicklung-frage-antwort-db.com.de

HTML5-Datei-API, die Datei vom Server herunterlädt und in der Sandbox speichert

Ich versuche, die HTML5-API zu verstehen. Ich entwerfe die Webanwendung, bei der der Browser-Client mehrere Dateien vom Server herunterladen muss. Der Benutzer führt etwas mit den heruntergeladenen Dateien und der Anwendung durch, um den Status auf der Benutzerfestplatte zu speichern. Ich verstehe, dass der Browser diese Dateien nur in seiner Sandbox speichern kann. Dies ist in Ordnung, solange der Benutzer diese Dateien beim zweiten Start der Anwendung abrufen kann. Muss ich BlobBuilder oder FileSaver verwenden? Ich bin hier ein bisschen verloren.

26
Mamadum

Ich werde Ihnen zeigen, wie Sie Dateien mit der XMLHttpRequest Level 2 herunterladen und mit der FileSystem API oder mit der FileSaver-Schnittstelle speichern.

Dateien herunterladen

Zum Herunterladen einer Datei verwenden Sie XMLHttpRequest Level 2 (auch bekannt als XHR2), das Cross-Origin-Anforderungen unterstützt, Fortschrittsereignisse hochlädt und binäre Daten hochlädt/herunterlädt. In dem Beitrag " New Tricks in XMLHttpRequest2 " gibt es viele Beispiele für die Verwendung von XHR2.

Um eine Datei als Blob herunterzuladen, müssen Sie lediglich die Variable responseType auf "Blob" angeben. Sie können auch die Typen "text", "arraybuffer" oder "document" verwenden. Die folgende Funktion lädt die Datei in die Variable url herunter und sendet sie an die Variable success:

function downloadFile(url, success) {
    var xhr = new XMLHttpRequest(); 
    xhr.open('GET', url, true); 
    xhr.responseType = "blob";
    xhr.onreadystatechange = function () { 
        if (xhr.readyState == 4) {
            if (success) success(xhr.response);
        }
    };
    xhr.send(null);
}

Die success-Rückmeldung erhält als Argument eine Instanz von Blob, die später geändert und gespeichert und/oder auf einen Server hochgeladen werden kann.

Dateien mit der FileSystem-API speichern

Wie die Can ich verwenden kann ... site weist darauf hin gibt es nicht viele Browser, die die FileSystem-API unterstützen. Für Firefox gibt es eine Erklärung für den fehlenden Support. Dazu müssen Sie Chrome verwenden.

Zuerst müssen Sie einen Speicherplatz anfordern, der entweder temporär oder dauerhaft sein kann. Wahrscheinlich möchten Sie einen dauerhaften Speicher haben. In diesem Fall müssen Sie im Vorfeld eine Quote an Speicherplatz anfordern ( einige Fakten ):

window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;
window.storageInfo = window.storageInfo || window.webkitStorageInfo;

// Request access to the file system
var fileSystem = null         // DOMFileSystem instance
  , fsType = PERSISTENT       // PERSISTENT vs. TEMPORARY storage 
  , fsSize = 10 * 1024 * 1024 // size (bytes) of needed space 
  ;

window.storageInfo.requestQuota(fsType, fsSize, function(gb) {
    window.requestFileSystem(fsType, gb, function(fs) {
        fileSystem = fs;
    }, errorHandler);
}, errorHandler);

Nun, da Sie Zugriff auf das Dateisystem haben, können Sie Dateien speichern und lesen. Die folgende Funktion kann einen Blob im angegebenen Pfad im Dateisystem speichern:

function saveFile(data, path) {
    if (!fileSystem) return;

    fileSystem.root.getFile(path, {create: true}, function(fileEntry) {
        fileEntry.createWriter(function(writer) {
            writer.write(data);
        }, errorHandler);
    }, errorHandler);
}

Eine Datei nach ihrem Pfad lesen:

function readFile(path, success) {
    fileSystem.root.getFile(path, {}, function(fileEntry) {
        fileEntry.file(function(file) {
            var reader = new FileReader();

            reader.onloadend = function(e) {
                if (success) success(this.result);
            };

            reader.readAsText(file);
        }, errorHandler);
    }, errorHandler);
}

Zusätzlich zur readAsText-Methode können Sie entsprechend der FileReader-APIreadAsArrayBuffer und readAsDataURL aufrufen.

Den FileSaver verwenden

Der Beitrag " Generierte Dateien auf Client-Seite speichern " erklärt die Verwendung dieser API sehr gut. Einige Browser benötigen möglicherweise die Datei FileSaver.js , um die Schnittstelle saveAs zu verwenden.

Wenn Sie es zusammen mit der downloadFile-Funktion verwenden, könnten Sie etwa Folgendes haben:

downloadFile('image.png', function(blob) {
    saveAs(blob, "image.png");
});

Natürlich wäre es sinnvoller, wenn der Benutzer das Bild visualisieren, bearbeiten und auf seiner Festplatte speichern könnte.

Fehlerhandler

Nur um das Beispiel zu erfüllen:

function errorHandler(e) {
    var msg = '';

    switch (e.code) {
        case FileError.QUOTA_EXCEEDED_ERR:
            msg = 'QUOTA_EXCEEDED_ERR';
            break;
        case FileError.NOT_FOUND_ERR:
            msg = 'NOT_FOUND_ERR';
            break;
        case FileError.SECURITY_ERR:
            msg = 'SECURITY_ERR';
            break;
        case FileError.INVALID_MODIFICATION_ERR:
            msg = 'INVALID_MODIFICATION_ERR';
            break;
        case FileError.INVALID_STATE_ERR:
            msg = 'INVALID_STATE_ERR';
            break;
        default:
            msg = 'Unknown Error';
            break;
    };

    console.log('Error: ' + msg);
}

Nützliche Links

65
mayconbordin

Wenn Sie nur HTML5-Browser unterstützen, können Sie das Attribut "Download" verwenden. Weitere Details finden Sie hier: http://updates.html5rocks.com/2011/08/Downloadingresources-in-HTML5-a-download

2
Trunal Bhanse

Mein Trick ist es, einfach IFRAMEs mit einem "src" -Attribut anzufügen, das auf Ihre mehrfachen Downloads verweist. Die Server-Site sollte die Dateien mit einem Header "disposition: attachment" senden. Anschließend versucht der Client, die Datei lokal zu speichern. Das einzige "Problem" besteht darin, dass die IFRAMEs als Schutt in der DOM-Struktur verbleiben, bis der Benutzer die Seite verlässt oder neu lädt. Machen Sie das IFRAME unsichtbar (z. B. width = 0; height = 0;), und Sie können loslegen! Alle Browser.

0
Martin Rode