2012-07-25 52 views
1

我试图找出从JavaScript启动的HTTP请求上传/下载二进制数据到Google AppEngine的Blobstore的最低数据开销方式。理想情况下,我想直接提交二进制数据,即未编码的8位值;也许在一个POST请求,看起来是这样的:通过HTTP请求将二进制数据上传到AppEngine Blobstore

... 
Content-Type: multipart/form-data; boundary=boundary; 

--boundary 
Content-Disposition: form-data; name="a"; filename="b" 
Content-Type: application/octet-stream 

@#^%(^Qtr... 
--boundary-- 

这里,@#^%(^Qtr...最好代表任意8位二进制数据。

具体来说,我想了解以下信息:

  • 是否有可能直接上传8位二进制数据,或者我需要对数据进行编码以某种方式,就像一个基地64 MIME编码?
  • 如果我使用不同的编码,Blobstore会将数据保存为8位二进制内部还是编码格式?即一个base-64编码会将我的存储成本增加33%?
  • 沿着同样的道路:编码开销是否会增加出站带宽成本?
  • 有没有更好的方法来格式化POST请求,所以我不需要想出一个boundary,它不会出现在我的二进制数据中?例如。有没有办法指定一个Content-Length而不是一个边界?
  • 在获取数据的GET请求中,我是否可以简单地希望二进制数据在返回字符串中结束,还是服务器将以某种方式自动编码数据?
  • 如果我需要使用一些编码,那么对于基本上随机的8位数据,支持的选项中哪一个最好? (2碱-64,UTF-8,成才人)

回答

1

即使我收到了Tumbleweed Badge对于这个问题,让我对我的进步反正如果有人报告在那里做护理:

这个问题横空出世,提出3个独立的问题:

  1. 上传数据到BLOBSTORE有效
  2. 确保BLOBSTORE将其保存在尽可能小的格式
  3. 寻找AW唉可靠地下载数据

让我们开始(3),因为这最终构成了最大的问题:

到目前为止,我还没有能够找到一种方法来下载真正的8-通过XHR将数据传输到浏览器。除非将数据下载到文件,否则使用像application/octet-stream这样的MIME类型将导致只有7位可靠地到达客户端。我发现最好的解决办法,是使用下面的MIME类型的数据:

text/plain; charset=ISO-8859-1 

这似乎是我测试过所有的浏览器支持:IE 8,Chrome浏览器21,FF 12.0,歌剧11.61, Windows下的Safari 5.1.2和Android 2.3.3。

由此,可以传送几乎所有的8位值,具有以下限制/注意事项:

  • 字符0×00被解释为在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会为这些字符返回错误代码,因此也需要避免这些错误。

总的来说,这给我们留下了250出了256个字符,我们可以使用的。随着数据所需的基础改变,这意味着传出数据开销低于0.5%,我想我可以。

所以,现在的问题(1)和(2):

由于进入的带宽是免费的,我已经决定减少有利于问题解决问题(1)的优先级(2)和(3)。原来,使用以下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==被以base64 MIME编码的数据由上述250个允许的字符(见http://en.wikipedia.org/wiki/Base64#Examples,GAE使用+和/作为最后2个字符)。编码是必要的(纠正我,如果我错了),因为使用字符串数据调用XHR send()函数将导致字符串的UTF-8编码,从而将服务器接收到的数据搞乱。不幸的是,将ArrayBuffers和Blob传递给send()函数在所有浏览器中都不可用,但尚未更好地规避此问题。

现在好消息:AppEngine BlobStore将自动正确解码这些数据并将其存储起来,无需开销!因此,使用base64编码只会导致来自客户端的较慢的数据上传速度,但不会导致额外的托管成本(除非可能有几个CPU周期用于解码)。

另外:AppEngine开发服务器将在管理控制台和检索到的BlobInfo记录中报告存储blob的编码大小(即大33%)。不过,生产服务器不存在此问题,并报告正确的Blob大小。

结论

使用内容传输编码base64上传的text/plain; charset=ISO-8859-1 Content-Type的二进制数据,这可能不包含的字符为0x00,0x81表示,0x8D,值为0x8F,0×90,和0x9D,导致可靠的数据传输,适用于许多经过测试的浏览器,其存储/传出带宽开销不到半个百分点。 base64编码数据的上传开销是33%,这比UTF-8的预期的50%(对于随机8位数据)要好,但仍然不理想。

我不知道的是:这是最佳解决方案,还是可以做得更好?任何人为了挑战?

相关问题