2017-05-02 4 views
0

私はURLの配列を持っています[URL1, URL2, URL3,...]:各要素は同じファイルのチャンクの1つへのリンクです。各チャンクは別々に暗号化され、他のすべてのチャンクと同じキーで暗号化されます。Array内のBlobを構築するArrayBufferをプッシュ

XMLHttpRequestで各チャンク(forEach関数内)をダウンロードします。 onload

  1. 各チャンクが最初
  2. を復号化され、各チャンクは、3つの第1のステップが行われたときに各ArrayBufferがアレイ(source
  3. にプッシュさArrayBuffersource
  4. に変換されます。各塊について(callbackvarによってステップ#1でインクリメントされる=== array.length)、ブロブは配列で構築される
  5. ブロブi FileReader APIでファイルとして保存されました& filesaver.js

1つのチャンクのファイルであれば、すべて正常に動作します。

複数チャンクの場合、#&#2の手順は正常ですが、最後のArrayBufferだけが配列にプッシュされているようです。私は何が欠けていますか?あなたはこれを試す、MyBlobBuilderの宣言を取る必要がある

私のコードの下に

// var for incrementation in forEach funtion 
var chunkdownloaded = 0; 
// 'clearfileurl' is the array of url's chunks :[URL1, URL2, URL3,...] 
clearfileurl.forEach(function(entry) { 
    var xhr = new XMLHttpRequest(); 
    var started_at = new Date(); 
    xhr.open('GET', entry, true); 
    xhr.responseType = 'text'; 

    // request progress 
    xhr.onprogress = function(pe) { 
     if (pe.lengthComputable) { 
      downloaderval.set((pe.loaded/pe.total) * 100); 
     } 
    }; 

    // on request's success 
    xhr.onload = function(e) { 
     if (this.status == 200) { 

      chunkdownloaded+=1; 
      var todecrypt = this.response; 

      // decrypt request's response: get a dataURI 
      try { 
       var bytesfile = CryptoJS.AES.decrypt(todecrypt.toString(), userKey); 
       var decryptedfile = bytesfile.toString(CryptoJS.enc.Utf8); 
      } catch(err) { 
       console.log (err); 
       return false; 
      } 

      //convert a dataURI to a Blob 
      var MyBlobBuilder = function() { 
       this.parts = []; 
      } 

      MyBlobBuilder.prototype.append = function(dataURI) { 
      //function dataURItoBlob(dataURI) { 
       // convert base64 to raw binary data held in a string 
       var byteString = atob(dataURI.split(',')[1]); 

       // separate out the mime component 
       // var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 

       // write the bytes of the string to an ArrayBuffer 
       var ab = new ArrayBuffer(byteString.length); 
       var ia = new Uint8Array(ab); 
       for (var i = 0; i < byteString.length; i++) { 
        ia[i] = byteString.charCodeAt(i); 
       } 
       this.parts.push(ab); 
       console.log('parts', this.parts) 
       this.blob = undefined; // Invalidate the blob 
      } 

      MyBlobBuilder.prototype.getBlob = function() { 
       if (!this.blob) { 
        console.log (this.parts); 
        this.blob = new Blob(this.parts); 
       } 
       return this.blob; 
      }; 

      var myBlobBuilder = new MyBlobBuilder(); 
      myBlobBuilder.append(decryptedfile); 

      // if all chunks are downloaded 
      if (chunkdownloaded === clearfileurl.length) { 
       // get the blob 
       var FinalFile = myBlobBuilder.getBlob(); 

       // launch consturction of a file with'FinalFile' inside FileReader API 
       var reader = new FileReader(); 
       reader.onload = function(e){ 
        // build & save on client the final file with 'file-saver' library 
        var FileSaver = require('file-saver'); 
        var file = new File([FinalFile], clearfilename, {type: clearfiletype}); 
        FileSaver.saveAs(file); 
       }; 
       reader.readAsText(FinalFile); 

      } else { 
       console.log('not yet'); 
      } 
     } 
    }; 
    // sending XMLHttpRequest 
    xhr.send(); 
}); 
+1

まあ、xhrロードイベントごとにMyBlobBuilderのインスタンスを1つ作成しているので、最終的にはすべて1つのdecryptedFileが含まれます。このオブジェクトのインスタンスを1つだけ共通のスコープ(つまりonloadハンドラから)で作成し、onloadハンドラのappendメソッドを呼び出します。 (注:私はコードを注意深く読まなかったので、いくつかの間違いがあるかもしれませんが、これはもっと明白です)。ええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええってあなたが解読したファイルが追加される順序を保証するものはありません。 – Kaiido

+0

@Kaiidoあなたは正しいですよ。もちろん、共通のスコープ内にMyBlobBuilderのインスタンスを1つだけ作成する必要がありました。復号化されたファイルの配列を正しい順序(元のURL配列からの配列: '[URL1、URL2、URL3、...]')で再構築するのを助けることができますか? – Ontokrat

答えて

1

// var for incrementation in forEach funtion 
var chunkdownloaded = 0; 

//convert a dataURI to a Blob 
var MyBlobBuilder = function() { 
    this.parts = []; 
} 

MyBlobBuilder.prototype.append = function(dataURI, index) { 
//function dataURItoBlob(dataURI) { 
    // convert base64 to raw binary data held in a string 
    var byteString = atob(dataURI.split(',')[1]); 

    // separate out the mime component 
    // var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 

    // write the bytes of the string to an ArrayBuffer 
    var ab = new ArrayBuffer(byteString.length); 
    var ia = new Uint8Array(ab); 
    for (var i = 0; i < byteString.length; i++) { 
     ia[i] = byteString.charCodeAt(i); 
    } 
    this.parts[index] = ab; 
    console.log('parts', this.parts) 
    this.blob = undefined; // Invalidate the blob 
} 

MyBlobBuilder.prototype.getBlob = function() { 
    if (!this.blob) { 
     console.log (this.parts); 
     this.blob = new Blob(this.parts); 
    } 
    return this.blob; 
}; 

var myBlobBuilder = new MyBlobBuilder(); 

// 'clearfileurl' is the array of url's chunks :[URL1, URL2, URL3,...] 
clearfileurl.forEach(function(entry, index) { 
    var xhr = new XMLHttpRequest(); 
    var started_at = new Date(); 
    xhr.open('GET', entry, true); 
    xhr.responseType = 'text'; 

    // request progress 
    xhr.onprogress = function(pe) { 
     if (pe.lengthComputable) { 
      downloaderval.set((pe.loaded/pe.total) * 100); 
     } 
    }; 

    // on request's success 
    xhr.onload = function(e) { 
     if (this.status == 200) { 

      chunkdownloaded+=1; 
      var todecrypt = this.response; 

      // decrypt request's response: get a dataURI 
      try { 
       var bytesfile = CryptoJS.AES.decrypt(todecrypt.toString(), userKey); 
       var decryptedfile = bytesfile.toString(CryptoJS.enc.Utf8); 
      } catch(err) { 
       console.log (err); 
       return false; 
      } 


      myBlobBuilder.append(decryptedfile, index); 

      // if all chunks are downloaded 
      if (chunkdownloaded === clearfileurl.length) { 
       // get the blob 
       var FinalFile = myBlobBuilder.getBlob(); 

       // launch consturction of a file with'FinalFile' inside FileReader API 
       var reader = new FileReader(); 
       reader.onload = function(e){ 
        // build & save on client the final file with 'file-saver' library 
        var FileSaver = require('file-saver'); 
        var file = new File([FinalFile], clearfilename, {type: clearfiletype}); 
        FileSaver.saveAs(file); 
       }; 
       reader.readAsText(FinalFile); 

      } else { 
       console.log('not yet'); 
      } 
     } 
    }; 
    // sending XMLHttpRequest 
    xhr.send(); 
}); 

*私はまた、ファイルがであることを保証するためにアペンド機能を更新編集正しい順序

+0

きれいで簡潔な答えがうまくいきます:ファイルが正しい順序であることを確認するための特別な感謝 - 非常に感謝します。今私はチャンク機能(すべてのチャンクが書かれているとは思われない)で私のスライスの問題を発見しました - 別の問題... – Ontokrat

関連する問題