C#, asp net.ajax разработка web-приложений, Javascript CSS
 
Задать вопрос asp.net ajax C#

Рубрики


Статьи


Подписка


Подписаться по RSS

Архив

 Полный архив по категориям

Популярные записи


Мои рекомендации



Есть достаточно простой способ сжатия траффика для сайта написаного на ASP.NET 

Организуется он следующим образом.

  1. Создаём HttpModule с именем HttpCompressionModule
  2. добавляем обработчик
    context.BeginRequest += new EventHandler(context_BeginRequest);
  3. В http заголовках находим Accept-Encoding и проверяем её на наличие значений gzip или deflate
  4. Если браузер поддерживает один из способов сжатия, добавляем соответствующий фильтр DeflateStream или GZipStream и не забываем указать Content-Encoding
  5. Ну и последжний шаг - добавляем HttpCompressionModule в список HttpModule в файле web.config
    <httpModules>
            <add name="HttpCompressionModule" type="HttpCompressionModule"/>
     </httpModules>

Код  класса для сжатия трафика сайта приведён ниже:

using System;
using System.IO;
using System.IO.Compression;
using System.Web;

public class HttpCompressionModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
    }

    private void context_BeginRequest(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication) sender;
        if (app.Request.Url.ToString().ToLower().IndexOf("aspx") < 0) return;
        string encodings = app.Request.Headers.Get("Accept-Encoding");
        if (encodings == null) return;

        Stream baseStream = app.Response.Filter;
        encodings = encodings.ToLower();

        if (encodings.Contains("gzip"))
        {
            app.Response.Filter = new GZipStream(baseStream,
                                                 CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "gzip");
        }
        else if (encodings.Contains("deflate"))
        {
            app.Response.Filter = new DeflateStream(baseStream,
                                                    CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "deflate");
        }
    }

    public void Dispose()
    {
    }
}

ЗЫ. По результатам тестирования могу сказать что сжатие страницы занимает около 1-1,5 милисикунд и сжимает размер страницы в 2-4 раза. Но всё таки не стоит принебрегать размером ViewState который к клиенту придёт в сжатом виде, а от него будет отсылаться в чистом виде. Это особенно актуально при использовании UpdatePanel, когда ответ сервера занимает десятки байт, а вот сам запрос на сервер потянет на десятки килобайт.

Попозже напишу о том как сжимать отдельно ViewState.

Wednesday, July 18, 2007 10:51:41 AM (E. Europe Standard Time, UTC+02:00)
Спасибо. Пригодилось.
Кирилл
Monday, October 15, 2007 1:17:36 PM (E. Europe Standard Time, UTC+02:00)
Большое спасибо за статью.
Пригодилось и помогло.
Есть лишь один небольшой вопрос. При асинхронной работе со страницами на котороых есть UpdatePanel генерируется ошибка: Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.
Как то можно от нее избавиться или нет?
Monday, October 15, 2007 3:00:37 PM (E. Europe Standard Time, UTC+02:00)
Можно, нужно просто выключать компрессию для AJAX запросов(они сами их жмут). Посмотри фидлером на такие запросы и посмотри по заголовкам запроса чем они отличаются от обычных (там какой то параметр в header добавляют) и для такого в context_BeginRequest делай просто return
Friday, November 16, 2007 3:10:44 PM (E. Europe Standard Time, UTC+02:00)
Добрый день.
Еще один вопрос. У меня почему то сжатие работает только в случае если я обращаюсь к приложению локально. А если выкладываю на тестовый сервер, то сжатия не происходит. Как можно выяснить причину? Мне кажется что заголовок "Accept-Encoding" каким-то образом теряется по дороге.
Thursday, December 06, 2007 5:30:08 PM (E. Europe Standard Time, UTC+02:00)
Niklegaloff
можно по подробнее - как решить проблему с AJAX ?
Friday, December 07, 2007 12:43:26 PM (E. Europe Standard Time, UTC+02:00)
Проблема решается следующим образом, в BeginRequest добавляются строки:

string s = app.Request.Headers.ToString();
if (s.IndexOf("ajax")>0) return;
if (s.IndexOf("urlencoded")>0) return;

И метод будет выглядеть вот так:
private void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication) sender;

string s = app.Request.Headers.ToString();
if (s.IndexOf("ajax")>0) return;
if (s.IndexOf("urlencoded")>0) return;
При асинхронном AJAX вызове в параметрах запроса присутствует слово ajax (ну и если не изменяет память в каких то случаях urlencoded). В этом случае мы просто не добавляем фильтр для сжатия выходного потока.
Friday, December 07, 2007 12:47:47 PM (E. Europe Standard Time, UTC+02:00)
NikLegaloff
Спасибо. Мне помогло.
Comments are closed.