How to Specify "Vary: Accept-Encoding" header in .htaccess

Google PageSpeed says I should "Specify a Vary: Accept-Encoding header" for JS and CSS. How do I do this in .htaccess?

169248 次浏览

I guess it's meant that you enable gzip compression for your css and js files, because that will enable the client to receive both gzip-encoded content and a plain content.

This is how to do it in apache2:

<IfModule mod_deflate.c>
#The following line is enough for .js and .css
AddOutputFilter DEFLATE js css


#The following line also enables compression by file content type, for the following list of Content-Type:s
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml


#The following lines are to avoid bugs with some browsers
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</IfModule>

And here's how to add the Vary Accept-Encoding header: [src]

<IfModule mod_headers.c>
<FilesMatch "\.(js|css|xml|gz)$">
Header append Vary: Accept-Encoding
</FilesMatch>
</IfModule>

The Vary: header tells the that the content served for this url will vary according to the value of a certain request header. Here it says that it will serve different content for clients who say they Accept-Encoding: gzip, deflate (a request header), than the content served to clients that do not send this header. The main advantage of this, AFAIK, is to let intermediate caching proxies know they need to have two different versions of the same url because of such change.

I'm afraid Aularon didn't provide enough steps to complete the process. With a little trial and error, I was able to successfully enable Gzipping on my dedicated WHM server.

Below are the steps:

  • Run EasyApache within WHM, select Deflate within the Exhaustive Options list, and rebuild the server.

  • Once done, goto Services Configuration >> Apache Configuration >> Include Editor >> Post VirtualHost Include, select All Versions, and then paste the mod_headers.c and mod_headers.c code (listed above in Aularon's post) on top of on another within the input field.

  • Once saved, I was seeing a 75.36% data savings on average! You can run a before and after test by using this HTTP Compression tool to see your own results: http://www.whatsmyip.org/http_compression/

Hope this works for you all!

  • Matt

This was driving me crazy, but it seems that aularon's edit was missing the colon after "Vary". So changing "Vary Accept-Encoding" to "Vary: Accept-Encoding" fixed the issue for me.

I would have commented below the post, but it doesn't seem like it will let me.

Anyhow, I hope this saves someone the same trouble I was having.

To gzip up your font files as well!

add "x-font/otf x-font/ttf x-font/eot"

as in:

AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml x-font/otf x-font/ttf x-font/eot

No need to specify or even check if the file is/has compressed, you can send it to every file, On every request.

It tells downstream proxies how to match future request headers to decide whether the cached response can be used rather than requesting a fresh one from the origin server.

<ifModule mod_headers.c>
Header unset Vary
Header set Vary "Accept-Encoding, X-HTTP-Method-Override, X-Forwarded-For, Remote-Address, X-Real-IP, X-Forwarded-Proto, X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Server"
</ifModule>
  • the unset is to fix some bugs in older GoDaddy hosting, optionally.

if anyone needs this for NGINX configuration file here is the snippet:

location ~* \.(js|css|xml|gz)$ {
add_header Vary "Accept-Encoding";
(... other headers or rules ...)
}

Many hours spent to clarify what was that. Please, read this post to get the advanced .HTACCESS codes and learn what they do.

You can use:

Header append Vary "Accept-Encoding"
#or
Header set Vary "Accept-Encoding"