Кто-нибудь получил HTTP-сжатие, работающее с ASP.NET? - PullRequest
0 голосов
/ 21 декабря 2010

Я потратил немало времени на это, но, похоже, никуда не денусь. У меня есть большая страница, которую я действительно хочу ускорить. Очевидное место для начала, кажется, сжатие HTTP, но я просто не могу заставить его работать на меня.

После долгих поисков я попробовал несколько вариантов кода ниже. Это вроде работает, но после обновления браузера результаты, похоже, рушатся. Они превращались в мусор, когда страница использовала кеширование. Если я отключаю кеширование, то страница кажется правильной, но я теряю свое форматирование CSS (сохраненное в отдельном файле) и получаю сообщение об ошибке, что включенный файл JS содержит недопустимые символы.

Большинство ресурсов, которые я нашел в Интернете, были либо очень старыми, либо были направлены на прямой доступ к IIS. Моя страница работает с учетной записью общего хостинга, и у меня нет прямого доступа к IIS7, на котором он работает.

protected void Application_BeginRequest(object sender, EventArgs e)
{
    // Implement HTTP compression
    if (Request["HTTP_X_MICROSOFTAJAX"] == null) // Avoid compressing AJAX calls
    {
        // Retrieve accepted encodings
        string encodings = Request.Headers.Get("Accept-Encoding");
        if (encodings != null)
        {
            // Verify support for or gzip (deflate takes preference)
            encodings = encodings.ToLower();
            if (encodings.Contains("gzip") || encodings == "*")
            {
                Response.Filter = new GZipStream(Response.Filter,
                    CompressionMode.Compress);
                Response.AppendHeader("Content-Encoding", "gzip");
                Response.Cache.VaryByHeaders["Accept-encoding"] = true;
            }
            else if (encodings.Contains("deflate"))
            {
                Response.Filter = new DeflateStream(Response.Filter,
                    CompressionMode.Compress);
                Response.AppendHeader("Content-Encoding", "deflate");
                Response.Cache.VaryByHeaders["Accept-encoding"] = true;
            }
        }
    }
}

Есть ли у кого-то успех с этим?

1 Ответ

1 голос
/ 21 декабря 2010

Я получил хорошие результаты, используя GZipStream и DeflateStream для прямой записи вывода, хотя я не знаком со свойством Response.Filter. Дайте этому водоворот:

string response = "your output body";
string accept = Request.Headers["Accept-Encoding"];
if(accept == null) accept = "";
if (response.Length < 100 || !(accept.Contains("deflate") || accept.Contains("gzip")))
    Response.Write(response);
else
{
    byte[] compressed;
    bool useDeflate = accept.Contains("deflate");
    using (MemoryStream stream = new MemoryStream())
    {
        using (Stream deflate = useDeflate
            ? (Stream)new DeflateStream(stream, CompressionMode.Compress, true)
            : (Stream)new GZipStream(stream, CompressionMode.Compress, true))
        using (StreamWriter writer = new StreamWriter(deflate))
            writer.Write(response);
        compressed = new byte[stream.Length];
        stream.Position = 0;
        stream.Read(compressed, 0, compressed.Length);
    }
    Response.Headers["Content-Encoding"] = useDeflate ? "deflate" : "gzip";
    Response.BinaryWrite(compressed);
}
...