この質問でタンブルウィード バッジを受け取りましたが、気になる人がいる場合に備えて、進捗状況を報告させてください。
この質問は、3 つの独立した問題を引き起こすことが判明しました。
- BlobStore へのデータの効率的なアップロード
- BlobStore が可能な限り小さい形式で保存することを確認する
- データを確実にダウンロードする方法を見つける
(3) から始めましょう。これが最大の問題を引き起こします。
これまでのところ、XHR 経由で真の 8 ビット データをブラウザにダウンロードする方法を見つけることができませんでした。application/octet-stream のような MIME タイプを使用すると、データがファイルにダウンロードされない限り、7 ビットのみが確実にクライアントに到達します。私が見つけた最善の解決策は、データに次の MIME タイプを使用することです。
text/plain; charset=ISO-8859-1
これは、私がテストしたすべてのブラウザーでサポートされているようです: IE 8、Chrome 21、FF 12.0、Opera 11.61、Windows の Safari 5.1.2、および Android 2.3.3。
これにより、ほぼすべての 8 ビット値を転送できますが、次の制限/注意事項があります。
- 文字 0x00 は、IE8 では入力文字列の末尾として解釈されるため、避ける必要があります。
- ほとんどのブラウザは文字セット ISO-8859-1 を代わりに Windows-1252 として解釈し、それに応じて文字 0x80 から 0x9F を変更します。ただし、変更は明確であるため、これは修正できます。( http://en.wikipedia.org/wiki/Windows-1252#Codepage_layoutを参照)
- 文字 0x81、0x8D、0x8F、0x90、0x9D は Windows-1252 文字セットで予約されており、Opera はこれらに対してエラー コードを返すため、これらも避ける必要があります。
全体として、これにより、使用できる 256 文字のうち 250 文字が残ります。データに必要な基準変更により、これは送信データのオーバーヘッドが 0.5% 未満であることを意味します。これで問題ないと思います。
それでは、問題 (1) と (2) について説明します。
着信帯域幅は無料なので、問題 (2) と (3) を優先して、問題 (1) を解決する優先度を下げることにしました。結局のところ、次の POST リクエストを使用すると、そのトリックが実行されます。
...
Content-Type: multipart/form-data; boundary=-
---
Content-Disposition: form-data; name="a"; filename="b"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: base64
abcd==
-----
abcd==
は、上記の許可された 250 文字で構成される base64-MIME エンコード データです ( http://en.wikipedia.org/wiki/Base64#Examplesを参照してください。GAEは最後の 2 文字として + と / を使用します)。文字列データで XHR send() 関数を呼び出すと、文字列の UTF-8 エンコードが行われ、サーバーが受信したデータが台無しになるため、エンコードが必要です (間違っている場合は修正してください)。残念ながら、ArrayBuffers と Blobs を send() 関数に渡すことは、まだすべてのブラウザーで利用できるわけではなく、この問題をよりエレガントに回避できます。
朗報です。AppEngine BlobStore は、このデータを自動的かつ正確にデコードし、オーバーヘッドなしで保存します。したがって、base64 エンコーディングを使用すると、クライアントからのデータ アップロードが遅くなるだけで、追加のホスティング コストは発生しません (デコードに数 CPU サイクルがかかる場合を除きます)。
余談: AppEngine 開発サーバーは、管理コンソールと取得された BlobInfo レコードの両方で、格納された BLOB のエンコードされたサイズ (つまり、33% 大きい) を報告します。ただし、運用サーバーにはこの問題はなく、正しい BLOB サイズが報告されます。
結論:
文字 0x00、0x81、0x8D、0x8F、0x90、および 0x9D を含まない可能性があるbase64
Content-Type のバイナリ データをアップロードするためにContent-Transfer-Encodingを使用すると、ストレージ/送信帯域幅のオーバーヘッドがある多くのテスト済みブラウザーで信頼性の高いデータ転送が行われます。 text/plain; charset=ISO-8859-1
0.5パーセント未満です。base64 でエンコードされたデータのアップロード オーバーヘッドは 33% であり、UTF-8 (ランダムな 8 ビット データの場合) で予想される 50% よりも優れていますが、それでも望ましいとは言えません。
私が知らないのは、これが最適な解決策なのか、それとももっとうまくできるのかということです。挑戦する人はいますか?