好的,所以我正在运行我自己的NanoHttpd分支(一个极简主义的Java Web服务器,虽然分叉很复杂),我不得不在它上面实现gzip压缩。
它运行良好,但事实证明,Linux 17m上的firefox 33.0根本不会执行gzipped js文件,虽然它们加载得很好,标题看起来还不行等。这不会发生在同一台带镀铬的电脑上,或者我尝试过的任何其他浏览器,但仍然是我必须修复的东西。
此外,如果我禁用gzipping,js资源执行得很好。我也尝试删除Connection:keep-alive,但这没有任何效果。
这是负责gzipping的代码:
private void sendAsFixedLength(OutputStream outputStream) throws IOException {
int pending = data != null ? data.available() : 0; // This is to support partial sends, see serveFile()
headerLines.add("Content-Length: "+pending+"\r\n");
boolean acceptEncoding = shouldAcceptEnc();
if(acceptEncoding){
headerLines.add("Content-Encoding: gzip\r\n");
}
headerLines.add("\r\n");
dumpHeaderLines(outputStream);//writes header to outputStream
if(acceptEncoding)
outputStream = new java.util.zip.GZIPOutputStream(outputStream);
if (requestMethod != Method.HEAD && data != null) {
int BUFFER_SIZE = 16 * 1024;
byte[] buff = new byte[BUFFER_SIZE];
while (pending > 0) {
int read = data.read(buff, 0, ((pending > BUFFER_SIZE) ? BUFFER_SIZE : pending));
if (read <= 0) {
break;
}
outputStream.write(buff, 0, read);
pending -= read;
}
}
outputStream.flush();
outputStream.close();
}
Fwiw,我复制此示例的示例没有关闭outputStream,但没有这样做,gzip压缩资源根本没有加载,而非gzip压缩资源仍然加载正常。所以我猜这部分是以某种方式关闭的。
编辑:firefox不会给出任何错误,它只是不会超出脚本,例如:
的index.html:
<html><head><script src="foo.js"></script></head></html>
foo.js:
alert("foo");
尽管资源已加载,但是没有做任何事情。控制台没有警告,没有任何警告。禁用gzip和其他浏览器时工作正常。
编辑2: 如果我直接请求foo.js,它加载就好了。
编辑3: 尝试检查响应&amp;在打开/关闭gzipping时使用TemperData的标头。 唯一的区别是当打开gzipping时,响应头中有Content-Encoding:gzip,这不是很令人惊讶。除此之外,100%的回应相等。
编辑4: 事实证明,从标题中删除内容长度使其再次起作用......不确定副作用,但至少这会更好地指出它。
答案 0 :(得分:1)
我认为您的问题的原因是您在压缩数据之前编写Content-Length
标题,这导致浏览器的信息不连贯。我想这取决于浏览器实现,它以一种或另一种方式处理这种情况,似乎Firefox以严格的方式做到了。
如果您不知道压缩数据的大小(这是可以理解的),您最好避免编写Content-Length
标题,这不是强制性的。