29

HTML5 API を理解しようとしています。ブラウザー クライアントがサーバーから複数のファイルをダウンロードする必要がある Web アプリケーションを設計しています。ユーザーは、ユーザーのハードドライブに状態を保存する必要があるよりも、ダウンロードしたファイルとアプリケーションで何かを実行します。ユーザーがアプリケーションを 2 回目に起動したときにそれらのファイルを取得できる限り、ブラウザーはこれらのファイルをサンドボックスにのみ保存できることを理解しています。BlobBuilder または FileSaver を使用する必要がありますか? 私はここで少し迷っています。

4

3 に答える 3

67

XMLHttpRequest レベル 2を使用してファイルをダウンロードし、 FileSystem APIまたはFileSaver インターフェイスを使用してファイルを保存する方法を紹介します。

##ファイルのダウンロード##

ファイルをダウンロードするには、XMLHttpRequest レベル 2 (別名 XHR2) を使用します。これは、クロスオリジン リクエスト、進捗イベントのアップロード、およびバイナリ データのアップロード/ダウンロードをサポートします。投稿「XMLHttpRequest2 の新しいトリック」には、XHR2 の使用例がたくさんあります。

ファイルを blob としてダウンロードするには、responseType「blob」に指定するだけです。「text」、「arraybuffer」、または「document」タイプも使用できます。以下の関数は、ファイルをダウンロードしてコールバックurlに送信します。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);
}

コールバックは、success後で変更して保存したり、サーバーにアップロードしたりできる Blob のインスタンスを引数として受け取ります。

##FileSystem API を使用したファイルの保存##

Can i use...サイトが指摘しているように、FileSystem API をサポートするブラウザーは多くありません。Firefoxの場合、サポートの欠如について説明があります。そのため、これを行うには Chrome を使用する必要があります。

最初にストレージ スペースを要求する必要があります。これは、一時的または永続的のいずれかです。おそらく永続的なストレージが必要になるでしょう。この場合、事前にストレージ容量のクォータをリクエストする必要があります (いくつかの事実):

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

ファイルシステムにアクセスできるようになったので、そこからファイルを保存および読み取ることができます。以下の関数は、指定されたパスの BLOB をファイル システムに保存できます。

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

パスでファイルを読み取るには、次のようにします。

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

メソッドに加えて、 FileReader APIreadAsTextに従って、およびを呼び出すことができます。readAsArrayBufferreadAsDataURL

##ファイルセーバーの使用##

投稿「生成されたファイルをクライアント側で保存する」は、この API の使用法を非常によく説明しています。一部のブラウザーでは、インターフェイスを使用するためにFileSaver.jssaveAsが必要になる場合があります。

関数と一緒に使用すると、次のdownloadFileようになります。

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

もちろん、ユーザーが画像を視覚化して操作し、ドライブに保存できれば、より理にかなっています。

###エラーハンドラ###

例を満たすために:

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

##便利なリンク##

于 2012-12-08T16:24:50.723 に答える
2

HTML5 ブラウザーのみをサポートする場合は、使用できる「ダウンロード」属性があります。詳細はこちら: http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download

于 2013-08-24T02:48:51.030 に答える
1

私の秘訣は、複数のダウンロードを指す「src」属性を IFRAME に単純に追加することです。サーバー サイトは "disposition: attachment" ヘッダーを付けてファイルを送信する必要があり、クライアントはファイルをローカルに保存しようとします。唯一の「問題」は、ユーザーがページを離れるかリロードするまで IFRAME が残骸として DOM ツリーに残ることです。IFRAME を非表示 (例: width=0; height=0;) にすると、準備完了です! すべてのブラウザ。

于 2015-08-04T19:49:55.750 に答える