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

7

81

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

Idolatrous answered 4/9, 2010 at 6:48 Comment(5)
Not sure why this was closed, just because it doesn't involve a programming language does not mean it's not related to coding.Afoul
@BlueRaja-DannyPflughoeft I agree, this has been viewed over 65100 times so I think it's a well searched topic not to mention I answer htaccess questions everyday.Ozzy
I know this is hold as hell, but the header Vary: Accept-Encoding will tell the browser to store in cache a version of the page based on the Content-Encoding header. You should see #1975916 and developers.google.com/speed/docs/best-practices/…Waltman
@IsmaelMiguel it will actually tell the client (and more important, any caching servers on the way), that the file differs for each variant of the clients Accept-Encoding` request header value, rather than each Content-Encoding variant of the server response header value.Paiz
@BlueRaja-DannyPflughoeft Because users with a lot of reputation and users seeking reputation build reputation by hunting down questions to close. Frustrating that it so often leads to questions being closed that shouldn't be.Governance
P
90

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.

Paiz answered 4/9, 2010 at 6:51 Comment(9)
I don't think this is it. My JS and CSS are already compressed. PageSpeed still complaining.Idolatrous
I think mod_deflate is supposed to send the Vary header by default.Nasia
I have done what you have mentioned above. The .js files still are not being compressed.Sil
@Andy; maybe your server doesn't have the "mod_deflate.c" module.Paiz
Hi, this didn't work for me either. I also tried putting the FilesMatch/Header lines within the mod_deflate.c block (since everything else is being gzip'd, I know it works). But still, pingdom is reporting that I should add the header..Guanajuato
Apache 2.2 does not require the mod_headers section in the answer above. mod_deflate already does what you need. httpd.apache.org/docs/2.2/mod/mod_deflate.htmlIncestuous
"Proxy cache servers should always store both the uncompressed and the compressed version of a file, because some clients do not accept GZip compressed files. However, a lot of them will not unless there is a Vary: Accept-Encoding header, so we will make sure to send one using mod_headers." - contao.org/en/news/optimizing-contao-for-google-page-speed.htmlKava
Some public proxies have bugs that do not detect the presence of the Content-Encoding response header. This can result in compressed versions being delivered to client browsers that cannot properly decompress the files. Set the Vary: Accept-Encoding response header. This instructs the proxies to cache two versions of the resource: one compressed, and one uncompressed. The correct version of the resource is delivered based on the client request header. - developers.google.com/speed/docs/best-practices/cachingKava
I was getting this suggestion from pagespeed too and I used just the second piece of code above: <IfModule mod_headers.c>.... and It worked like a charm.. Note: that i enabled gzip compression in my cpanel first... thanksAlbarran
G
4

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
Galloping answered 18/8, 2011 at 22:53 Comment(0)
E
3

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
Erubescence answered 1/8, 2012 at 18:21 Comment(0)
C
1

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.

Cyrene answered 21/6, 2012 at 19:51 Comment(1)
Are you sure this makes a difference? In the 2.2 docs none of the examples include the colon: httpd.apache.org/docs/2.2/mod/mod_headers.htmlRhiana
B
1

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 ...)
}
Baeda answered 17/8, 2016 at 8:9 Comment(0)
M
1

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"
Mohenjodaro answered 22/8, 2016 at 19:33 Comment(0)
B
0

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.
Bronchia answered 13/1, 2016 at 4:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.