如何从 javascript 有效地访问 gzipped xml?
我需要从 javascript(实际上是从 Greasemonkey)有效地访问一个大的 gzipped xml 文件。 不幸的是,服务器不提供 Content-Encoding 标头,并且 Content-Type 是“application/x-gzip”,因此 Firefox 不会(据我所知)自动膨胀它。 如果有一种方法可以伪造 Firefox,那将是理想的选择。除此之外,我需要某种方法来有效地进行膨胀……我现在使用的方法大约需要 30 秒来压缩 1.2Mb gzip 压缩文件;我希望能在 5 秒内完成。
(我正在处理的 Greasemonkey 脚本不能有任何其他外部服务器依赖项,因此代理和呈现内容编码标头不是一个选项。)
我现在正在做的事情,我已经从多个地方修补在一起。为了不受干扰地接收二进制数据,我使用 firefox XMLHTTPRequest overrideMimeType 扩展:
$.ajax(url, {
dataType:'text',
beforeSend:function(xhr){
xhr.overrideMimeType('text/plain; charset=x-user-defined')
},
success:function(data){
var blob='';
for (i=0; i<data.length; ++i)
blob += String.fromCharCode(data.charCodeAt(i) & 0xff);
...
然后膨胀,使用 https://github.com/ 的稍微修改和内联副本dankogai/js-deflate/blob/master/rawinflate.js (还有其他几个 javascript inflate 库,据我所知,所有这些库都是基于较旧的库 http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt)。这是慢得可怕的部分。
// blithely assuming the gzip header won't change,
// strip a fixed number of bytes from the front
deflated=RawDeflate.inflate(blob.substring(22,blob.length-8));
然后将其弹出到一个 innerHTML 属性中来解析它:(
xmlcontainer=$('<div>');
// remove <?xml...> prolog
xmlcontainer.html(deflated.substring(45));
xmldoc=xmldoc.children();
我知道最后一点可以使用 DOMParser 的 parseFromString 更正确地完成,但我还没有得到它的工作。)
I need to efficently access a large gzipped xml file from javascript (actually from Greasemonkey).
Unfortunately, the server doesn't provide a Content-Encoding header, and Content-Type is "application/x-gzip", so firefox will not (as far as I can tell) automatically inflate it.
If there's a way to fake firefox out, that would be ideal. Short of that, I need some way to efficiently do the inflation...what I'm using now takes about 30 seconds to deflate the 1.2Mb gzipped file; I'd like to get it down under 5 seconds.
(The Greasemonkey script I'm working on can't have any other external server dependencies, so proxying and presenting a Content-Encoding header isn't an option.)
What I'm doing now, I've patched together from several places. To receive the binary data unmolested, I'm using the firefox XMLHTTPRequest overrideMimeType extension:
$.ajax(url, {
dataType:'text',
beforeSend:function(xhr){
xhr.overrideMimeType('text/plain; charset=x-user-defined')
},
success:function(data){
var blob='';
for (i=0; i<data.length; ++i)
blob += String.fromCharCode(data.charCodeAt(i) & 0xff);
...
Then inflating, using a slightly modified and inlined copy of https://github.com/dankogai/js-deflate/blob/master/rawinflate.js (there are several other javascript inflate libraries out there, all as far as I can tell based on an older library http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt). This is the horrifically slow part.
// blithely assuming the gzip header won't change,
// strip a fixed number of bytes from the front
deflated=RawDeflate.inflate(blob.substring(22,blob.length-8));
Then popping it in an innerHTML property to parse it:
xmlcontainer=$('<div>');
// remove <?xml...> prolog
xmlcontainer.html(deflated.substring(45));
xmldoc=xmldoc.children();
(I know the last bit could be more properly done with DOMParser's parseFromString, but I didn't get that working yet.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用此配置您将无法获得明显更好的结果**。
JavaScript 太慢,无法按预期快速膨胀,并且您无法从 JS 可靠地调用二进制文件 - 除非将数据 AJAX 传输到您自己的服务器(可以是本地 PC)。
您的改进选项似乎是:
让浏览器自动扩充内容。如果您已尝试使用
overrideMimeType
来设置application/x-gzip
,您可以尝试使用 GM_xmlhttpRequest 代替(这是一个远景)。将其从 GM 脚本转换为 Firefox 插件。作为附加组件,您可以访问二进制文件,例如 7-Zip,甚至可以访问浏览器的 inflate 方法。您或许也可以更轻松地欺骗 mimetype。
**我确实注意到了一些微不足道的机会来加速膨胀的 JS...比如
for
循环内的length
检查。唉,考虑到细节,可能不会购买超过一两秒。You're just not going to be able to do noticeably better with this configuration**.
JavaScript is too slow to inflate as fast as desired, and you can't call a binary reliably from JS -- unless AJAXing the data to your own server (which can be the local PC).
Your options for improvement would seem to be:
Get the browser to automatically inflate the content. If you have already tried using
overrideMimeType
to setapplication/x-gzip
, you might try using GM_xmlhttpRequest instead (it's a long shot).Convert this from a GM script to a Firefox add-on. As an add-on, you can access binaries, like 7-Zip, and might even have access to the browser's inflate method. You could probably spoof the mimetype more easily too.
**I did notice some trivial opportunities to speed up that inflating JS... things like
length
checks insidefor
loops. Alas, given the particulars, probably not going to buy more than a second or two.