2

次のコードを使用して、生成されたzipファイルをchrome拡張内からディスクに保存しようとしています:

function sendFile (nm, file) {
  var a = document.createElement('a');
  a.href = window.URL.createObjectURL(file);
  a.download = nm; // file name
  a.style.display = 'none';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}
function downloadZip (nm) {
  window.URL = window.webkitURL || window.URL;
  var content;
  content = zip.generate();
  var file = new Blob ([content], {type:'application/base64'});
  sendFile ("x.b64", file);
  content = zip.generate({base64:false});
  var file = new Blob ([content], {type:'application/binary'});
  sendFile ("x.zip", file);
}

base64 -d現在、これにより zip の内容が 2 つのバージョンで保存されます。最初のバージョンは base64 でエンコードされており、結果の zip でデコードすると問題ありません。
2 番目のバージョンは生データ (zip ファイル) を保存するだけですが、この生データは utf-8 でエンコードされてディスクに届きます。(各値 >= 0x80 の前に 0xc2 が付加されます)。では、この utf-8 エンコーディングを取り除くにはどうすればよいでしょうか? のようなさまざまな型文字列を試しapplication/zipたり、型情報を完全に省略したりして、常に utf-8 エンコーディングで到着します。また、ブラウザにbase64データ(最初のケース)を保存/変換させて、ディスクにデコードされたバイナリデータとして届くようにする方法にも興味があります... Chromeバージョン23.0.1271.95 mを使用しています

PS: ブラウザ内の hexdump ユーティリティで分析した 2 番目のコンテンツ: utf-8 エンコーディングが含まれていません (または、hexdump が暗黙的な変換を行うものを呼び出します)。完全を期すために (申し訳ありませんが、c から転置しただけなので、それほどクールな js コードではない可能性があります)、ここに追加します。

function hex (bytes, val) {
  var ret="";
  var tmp="";
  for (var i=0;i<bytes;i++) {
    tmp=val.toString (16);
    if (tmp.length<2)
      tmp="0"+tmp;
    ret=tmp+ret;
    val>>=8;
  }
  return ret;
}
function hexdump (buf, len) {
  var p=0;
  while (p<len) {
    line=hex (2,p);
    var i;
    for (i=0;i<16;i++) {
      if (i==8)
        line +=" ";
      if (p+i<len)
        line+=" "+hex(1,buf.charCodeAt(p+i));
      else
        line+="   ";
    }
    line+=" |";
    for (i=0;i<16;i++) {
      if (p+i<len) {
        var cc=buf.charCodeAt (p+i);
        line+= ((cc>=32)&&(cc<=127)&&(cc!='|')?String.fromCharCode(cc):'.');
      }
    }
    p+=16;
    console.log (line);
  }
}
4

1 に答える 1

2

ワーキングドラフトから:

element が DOMString の場合、次のサブステップを実行します。

  • WebIDL [WebIDL] でそれを行うためのアルゴリズムを使用して、要素を一連の Unicode 文字 [Unicode] に変換した結果を s とする。

  • s を UTF-8 としてエンコードし、結果のバイトをバイトに追加します。

そのため、文字列は常に UTF-8 に変換され、これに影響するパラメーターはありません。base64 文字列にはコードポイントごとに 1 バイトに一致する文字しか含まれておらず、コードポイントとバイトが同じ値を持つため、これは base64 文字列には影響しません。幸いなことBlobに、下位レベルのインターフェイス (ダイレクト バイト) が公開されているため、その制限はあまり重要ではありません。

あなたはこれを行うことができます:

var binaryString = zip.generate({base64: false}), //By glancing over the source I trust the string is in "binary" form
    len = binaryString.length,    //I.E. having only code points 0 - 255 that represent bytes
    bytes = new Uint8Array(len);

for( var i = 0; i < len; ++i ) {
    bytes[i] = binaryString.charCodeAt(i);
}

var file = new Blob([bytes], {type:'application/zip'});
sendFile( "myzip.zip", file );
于 2012-12-10T19:15:57.730 に答える