从.ashx GZipping Javascript在浏览器中返回解码错误

时间:2011-11-12 19:57:12

标签: c# asp.net gzip

背景

我正在设置一个通用处理程序:

  • 结合&压缩Javascript和CSS文件
  • 缓存GZip版本&非GZip版本
  • 根据请求提供适当的版本

我在OSX 10.7.2上的MonoDevelop v2.8.2中工作

问题

由于我想要缓存GZip压缩版本,我需要在不使用响应过滤器的情况下进行GZip

使用this代码,我可以成功压缩和解压缩服务器上的字符串,但当我将其提供给客户端时,我得到:

  • 错误330(net :: ERR_CONTENT_DECODING_FAILED):未知错误。 (镀铬)
  • 无法解码原始数据(Safari)
  • 您尝试查看的页面无法显示,因为它使用的是无效或不受支持的压缩形式。 (Firefox)的

相关代码

string sCompiled =null;
if(bCanGZip)
{
    context.Response.AddHeader("Content-Encoding", "gzip");
    bHasValue = CurrentCache.CompiledScripts.TryGetValue(context.Request.Url.ToString() + "GZIP", out sCompiled);
}

//...
//Process files if bHasVale is false
//Compress result of file concatination/minification

//Compression method
public static string CompressString(string text)
{
    UTF8Encoding encoding = new UTF8Encoding(false);

    byte[] buffer = encoding.GetBytes(text);
    using(MemoryStream memoryStream = new MemoryStream()){
        using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
        {
            gZipStream.Write(buffer, 0, buffer.Length);

        }
        memoryStream.Position = 0;

        byte[] compressedData = new byte[memoryStream.Length];
        memoryStream.Read(compressedData, 0, compressedData.Length);

        byte[] gZipBuffer = new byte[compressedData.Length + 4];
        Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
        Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
        return Convert.ToBase64String(gZipBuffer);

    }

}

//...
//Return value
switch(Type){
    case FileType.CSS:
        context.Response.ContentType = "text/css";  
        break;
    case FileType.JS:
        context.Response.ContentType = "application/javascript"; 
        break;
}
context.Response.AddHeader("Content-Length", sCompiled.Length.ToString());
context.Response.Clear();

context.Response.Write(sCompiled);  

尝试解决

因为我不确定这些行:

byte[] gZipBuffer = new byte[compressedData.Length + 4];
Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);

正在完成,我尝试删除它们。

我尝试使用不同的编码/选项。

此时我真的不确定如何解决问题,因为我不知道错误的来源(编码/压缩/其他)。

非常感谢任何帮助!

我在这个主题上找到的其他资源

1 个答案:

答案 0 :(得分:2)

这是其中一件事,一旦你解释了问题,你很快就会找到答案。

我需要把回复写成Binary。因此修改压缩算法以返回字节数组:

public static byte[] CompressStringToArray(string text){
    UTF8Encoding encoding = new UTF8Encoding(false);

    byte[] buffer = encoding.GetBytes(text);
    using(MemoryStream memoryStream = new MemoryStream()){
        using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
        {
            gZipStream.Write(buffer, 0, buffer.Length);

        }
        memoryStream.Position = 0;

        byte[] compressedData = new byte[memoryStream.Length];
        memoryStream.Read(compressedData, 0, compressedData.Length);

        return compressedData;
    }
}

然后致电:

//Writes a byte buffer without encoding the response stream
context.Response.BinaryWrite(GZipTools.CompressStringToArray(sCompiled));

解决问题。希望这有助于其他将面临同样问题的人。