GZipping Javascript из .ashx возвращает ошибку декодирования в браузере - PullRequest
3 голосов
/ 12 ноября 2011

Фон

Я настраиваю общий обработчик для:

  • Объединение и сжатие файлов JavaScript и CSS
  • Кэширование версии GZip и версии без GZip
  • Подать соответствующую версию на основании запроса

Я работаю в MonoDevelop v2.8.2 на OSX 10.7.2

Задача

Поскольку я хочу кэшировать версию GZipped, мне нужно GZip без использования фильтра ответов

Используя этот код, я могу успешно сжать и распаковать строку на сервере, но когда я передаю ее клиенту, я получаю:

  • Ошибка 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 Ответ

2 голосов
/ 13 ноября 2011

Это одна из тех вещей, где, как только вы объясните свою проблему, вы быстро найдете ответ.

Мне нужно выписать ответ как 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));

Решает проблему. Надеюсь, это поможет другим, кто столкнется с той же проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...