Làm thế nào để thực hiện nén GZip trong ASP.NET?


81

Tôi đang cố gắng triển khai nén GZip cho trang asp.net của mình (bao gồm các tệp CSS và JS của tôi). Tôi đã thử mã sau, nhưng nó chỉ nén trang .aspx của tôi (tìm thấy nó từ YSlow )

HttpContext context = HttpContext.Current;
context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
HttpContext.Current.Response.AppendHeader("Content-encoding", "gzip");
HttpContext.Current.Response.Cache.VaryByHeaders["Accept-encoding"] = true;

Đoạn mã trên chỉ nén mã trang .aspx của tôi (đánh dấu) chứ không phải các tệp CSS và JS được bao gồm dưới dạng tệp bên ngoài. Vui lòng cho tôi biết làm thế nào tôi có thể thực hiện nén GZip trong ASP.NET bằng cách sử dụng mã (vì tôi đang ở trên máy chủ lưu trữ được chia sẻ nơi tôi không có quyền truy cập vào cấu hình Máy chủ IIS). Và trong đoạn mã trên, tôi không nhận được hai dòng cuối cùng, tại sao chúng được sử dụng và mục đích của những dòng này là gì. Vui lòng giải thích!


Không hoàn toàn trùng lặp: stackoverflow.com/questions/6992524
jpaugh

Câu trả lời:


28

Để nén các tệp JS & CSS, bạn thực sự phải xử lý điều đó ở cấp IIS, vì các tệp này được hiển thị trực tiếp mà không cần thời gian chạy ASP.NET.

Bạn có thể tạo ánh xạ tiện ích mở rộng JSX & CSSX trong IIS tới aspnet_isapi.dll và sau đó tận dụng mã zip của bạn, nhưng IIS có thể thực hiện công việc này tốt hơn cho bạn.

Tiêu đề mã hóa nội dung cho trình duyệt biết rằng trình duyệt cần giải nén nội dung trước khi hiển thị. Dù sao thì một số trình duyệt cũng đủ thông minh để tìm ra điều này, dựa trên hình dạng của nội dung, nhưng tốt hơn là bạn nên chỉ ra.

Cài đặt bộ đệm ẩn mã hóa chấp nhận ở đó để phiên bản đã lưu trong bộ đệm ẩn của nội dung đã nén sẽ không được gửi đến trình duyệt chỉ yêu cầu văn bản / html.


4
Xin chào @Ben, Bạn có thể vui lòng cho tôi biết cách nén tệp của tôi bằng IIS không, tất cả cài đặt tôi phải thực hiện là gì, Mặc dù tôi không có quyền truy cập vào cấu hình IIS, nhưng tôi sẽ cố gắng thực hiện. Vui lòng cho tôi biết cách nén tệp bằng IIS ?? Cảm ơn!
Prashant

4
stackoverflow.com/a/6992948/8479 nêu chi tiết về thay đổi đơn giản đối với web.config cần cho IIS7 trở lên.
Rory

47

Đây là giải pháp cho các tệp css và javascript. Thêm mã sau vào bên trong tệp web.config của bạn:

  <httpCompression>
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
    <dynamicTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </dynamicTypes>
    <staticTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </staticTypes>
  </httpCompression>
  <urlCompression doStaticCompression="true" doDynamicCompression="true"/>

Tín dụng: Cách GZip trên ASP.NET và GoDaddy


4
dòng cuối cùng nên được gỡ bỏ
JeffT

đúng, nhưng tôi thực sự muốn thêm mở <system.webServer> ... để chúng tôi biết nơi đặt cấu hình.
Carlos R Balebona,

Tôi đã thêm cùng một mã nhưng các tệp không được nén
Zeeshan Ahmad Khalil

Tôi có cần thêm thứ gì khác không?
Zeeshan Ahmad Khalil

16

điều này có thể hữu ích cho bạn khi dùng thử, điều này chấp nhận nén deflate và gzip.

    void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;
        string acceptEncoding = app.Request.Headers["Accept-Encoding"];
        Stream prevUncompressedStream = app.Response.Filter;

        if (app.Context.CurrentHandler == null)
            return;

        if (!(app.Context.CurrentHandler is System.Web.UI.Page ||
            app.Context.CurrentHandler.GetType().Name == "SyncSessionlessHandler") ||
            app.Request["HTTP_X_MICROSOFTAJAX"] != null)
            return;

        if (acceptEncoding == null || acceptEncoding.Length == 0)
            return;

        acceptEncoding = acceptEncoding.ToLower();

        if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
        {
            // deflate
            app.Response.Filter = new DeflateStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "deflate");
        }
        else if (acceptEncoding.Contains("gzip"))
        {
            // gzip
            app.Response.Filter = new GZipStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "gzip");
        }
    } 

2
Cảm ơn rất nhiều cho mã này. Tôi cần gzip / deflate nội dung trên một trang web cụ thể mà tôi không có quyền truy cập vào bảng điều khiển IIS và điều này đã giúp tôi. Tuy nhiên, chỉ có một câu hỏi: Mã này dường như đang làm giảm tốc tất cả các tệp aspx và gziping CSS và ScriptResources, nhưng nó không gziping bất kỳ tệp .js nào. Có một cách để làm điều đó? Cảm ơn.
Rafael Merlin,

Điều này là sai, là bạn không xử lý giảng dạy chất lượng như thế này: gzip;q=0,deflate. singular.co.nz/2008/07/…
oligofren

11

Lý do nó chỉ nén tệp ASPX của bạn là mã bạn đã viết chỉ được nhúng trong tệp ASPX. Tệp ASPX là một yêu cầu riêng biệt với bất kỳ nội dung được liên kết nào mà nó chứa. Vì vậy, nếu bạn có một trang ASPX chứa:

<img src="www.example.com\exampleimg.jpg" alt="example" />

Điều này sẽ lên tới 2 yêu cầu (ngoài tra cứu DNS) từ trình duyệt của bạn tới các tài nguyên:

  1. cho trang aspx và
  2. cho hình ảnh được chứa bởi trang aspx.

Mỗi yêu cầu có hơi phản hồi riêng. Mã bạn đã đăng chỉ được đính kèm vào luồng phản hồi ASPX, đó là lý do tại sao chỉ trang ASPX của bạn đang được nén. Các dòng 1 & 2 của mã đã đăng của bạn về cơ bản đang tiếp quản luồng phản hồi bình thường của trang và chèn một số mã "người trung gian" mà trong trường hợp này là ăn và nén luồng đầu ra bình thường bằng một luồng GZip và thay vào đó gửi luồng đó xuống dây.

Dòng 3 & 4 đang thiết lập tiêu đề phản hồi. Tất cả các yêu cầu và phản hồi http đều có tiêu đề được gửi trước nội dung. Chúng thiết lập yêu cầu / phản hồi để máy chủ và máy khách biết những gì đang được gửi và cách thức.

Trong trường hợp này, Dòng 3 thông báo cho trình duyệt máy khách rằng luồng phản hồi được nén qua gzip và do đó cần được giải nén bởi trình duyệt khách trước khi hiển thị.

Và Dòng 4 chỉ đơn giản là bật tiêu đề Chấp nhận-Mã hóa của phản hồi. Nếu không thì điều này sẽ không có trong phản hồi.

Có những mô-đun có thể cắm được mà bạn có thể ghi / lấy cho phép bạn nén nhiều loại MIME khác như * .js và * .css nhưng tốt hơn hết bạn chỉ nên sử dụng chức năng nén tích hợp của IIS.

Bạn chưa cho biết bạn đang sử dụng phiên bản nào của IIS nhưng nếu đó là IIS 7.0, bạn sẽ phải bao gồm những thứ như sau vào <system.webserver>phần của tệp web.config của bạn:

<httpCompression> 
  <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" /> 
 <staticTypes>
         <add mimeType="text/*" enabled="true" />
      </staticTypes>
</httpCompression> 
<urlCompression doStaticCompression="true" /> 

..

Richard


Giới thiệu thực sự awsome
Rakeshyadvanshi

3

Trong IIS7, tất cả các yêu cầu đều đi tới .net, vì vậy bạn sẽ phải tạo một HttpModule để thêm các tiêu đề đó vào tất cả các phản hồi.

Nếu không có IIS7 và trên lưu trữ được chia sẻ, bạn sẽ phải tạo một trình xử lý ánh xạ phần mở rộng tệp .net mà bạn không sử dụng (như .asmx) và trong web.config chỉ định rằng các tệp .asmx đi đến HttpHandler của bạn. để viết lại đường dẫn thành .jpg hoặc bất cứ thứ gì và đặt cả tiêu đề ở đó.


2

Để trả lời câu hỏi cuối cùng của bạn. Hai dòng đó đặt tiêu đề HTTP cho phản hồi được gửi trở lại trình duyệt. Content-Encodingcho trình duyệt biết rằng phản hồi được mã hóa dưới dạng gzip và nó cần được giải mã. Dòng cuối cùng thêm Accept-Encodingvào tiêu đề Vary . Với điều này, trình duyệt hoặc proxy có thể xác định xem phản hồi là duy nhất hay bị ảnh hưởng bởi một số tiêu đề khác và điều chỉnh bộ nhớ đệm của chúng.


0

Thêm phần mở rộng .aspx vào tệp .css hoặc .js. Sử dụng <% @ Page ContentType = "text / css"%> hoặc javascript trong tệp để phân phối tệp với kiểu MIME chính xác. & sử dụng Ghi lại URL để ẩn điều này khỏi trình duyệt tác nhân người dùng. Tiêu đề phản hồi mã hóa nội dung được thêm gzip để chuyển tải rằng gzip là phương pháp được sử dụng để thực hiện nén. Tiêu đề phản hồi thay đổi được đặt thành Chấp nhận-Mã hóa để tất cả bộ nhớ đệm biết trang nào (được nén hoặc không được nén) sẽ được cung cấp tùy thuộc vào tiêu đề Mã hóa Chấp nhận của yêu cầu. Tôi đã giải thích chi tiết về điều này tại https://stackoverflow.com/a/14509007/1624169


0

Bạn chỉ có thể thêm phần sau vào tệp web.config của mình trong <system.webServer>phần tử:

<urlCompression doStaticCompression="true" doDynamicCompression="true" />

LƯU Ý: Nếu bạn đang sử dụng phiên bản IIS cũ hơn (nhỏ hơn v7.5), bạn có thể muốn đặt doDynamicCompression thành false vì quá trình này tốn nhiều CPU. Những vấn đề này đã được giải quyết trong IIS 7.5.

Tham khảo: https://docs.microsoft.com/en-us/iis/configuration/system.webserver/urlcompression


0

Làm điều đó với tệp web.config

<system.webServer>
    <httpCompression>
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
        <dynamicTypes>
            <add mimeType="text/*" enabled="true"/>
            <add mimeType="message/*" enabled="true"/>
            <add mimeType="application/javascript" enabled="true"/>
            <add mimeType="*/*" enabled="false"/>
        </dynamicTypes>
        <staticTypes>
            <add mimeType="text/*" enabled="true"/>
            <add mimeType="message/*" enabled="true"/>
            <add mimeType="application/javascript" enabled="true"/>
            <add mimeType="*/*" enabled="false"/>
        </staticTypes>
    </httpCompression>
    <urlCompression doStaticCompression="true" doDynamicCompression="true"/>
</system.webServer>

Hoặc bạn có thể làm điều đó thông qua IIS. Để nén các tệp JS & CSS, bạn thực sự phải xử lý điều đó ở cấp IIS, vì các tệp này được hiển thị trực tiếp mà không cần thời gian chạy ASP.NET.

Bạn có thể tạo ánh xạ tiện ích mở rộng JSX & CSSX trong IIS tới aspnet_isapi.dll và sau đó tận dụng mã zip của bạn, nhưng IIS có thể thực hiện công việc này tốt hơn cho bạn.

Tiêu đề mã hóa nội dung cho trình duyệt biết rằng trình duyệt cần giải nén nội dung trước khi hiển thị. Dù sao thì một số trình duyệt cũng đủ thông minh để tìm ra điều này, dựa trên hình dạng của nội dung, nhưng tốt hơn là bạn nên chỉ ra.

Cài đặt bộ đệm ẩn mã hóa chấp nhận ở đó để phiên bản đã lưu trong bộ đệm ẩn của nội dung đã nén sẽ không được gửi đến trình duyệt chỉ yêu cầu văn bản / html.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.