I've been trying to figure this one out for a few days now and have finally made a simplified enough test environment so that I can post this question with several examples.
The problem I'm running into is that my htaccess file is ignoring both the <If>
and <Else>
conditions. I am using Apache version 2.4.29 which does support this feature. Likewise, when I save the htaccess file, I do not get a 500-level error– the site works just fine (besides these being ignored).
My use case is that I'd like to listen for a query parameter and change the Cache-Control header based on whether that query parameter exists. I'm sure others would disagree with this premise and while I'm curious what a better solution would be, I would like to get to the bottom of this particular issue.
I've tried feeding several conditions to the <If>
thinking that maybe it just didn't like the format or that I was doing something wrong there, but I've now simplified it to be simply <If false>
to try to force the <Else>
side of the conditional. No matter what I do, neither side of the conditional is working– it is simply ignored completely.
Am I doing something wrong? I believe my syntax matches the documentation , but maybe I'm missing something... While I do have a lot of experience writing .htaccess files, I will admit I am far from an Apache expert.
I made a webpage that simply loads a single image.png
file and I read the Cache-Control header in Chrome DevTools.
.htaccess file contents:
<FilesMatch "png">
Header set Cache-Control "max-age=123, public"
</FilesMatch>
<If false>
<FilesMatch "png">
Header unset Cache-Control
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</FilesMatch>
</If>
<Else>
<FilesMatch "png">
Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
</Else>
Expected: The Cache-Control
max-age
should be 31536000
Actual: The Cache-Control
max-age
is 123
.htaccess file contents:
<If false>
<FilesMatch "png">
Header unset Cache-Control
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</FilesMatch>
</If>
<Else>
<FilesMatch "png">
Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
</Else>
Expected: The Cache-Control
max-age
should be 31536000
Actual: No Cache-Control
header exists at all
Edit: A clue has emerged that I am able to use 301 RedirectMatch inside the If/Else conditions, so it seems like the cache control headers are what is being ignored from within the conditionals... If that is the case, I'm curious what other options I have to make my use case (described above) work.
Edit 2: Another clue is that without the <FilesMatch>
line, the Cache-Control max-age header is applied as expected (just not to the right files).
So I found a work-around for my specific use-case which is why I am "answering" my own question, but I am not "accepting" this answer as it does not resolve the core problem. I wanted to provide this for anyone who stumbles upon this issue in the future.
What I found was that <FilesMatch>
was what was being ignored inside of <If>
and <Else>
conditions. Redirects and headers could be set without a problem within them.
So for my use-case, I flipped the logic around. I set the regular cache lengths as I wanted for individual file types using <FilesMatch>
(outside of any conditionals). Then, I added an <If>
condition to check for the query string, and if true it would unset all Cache-Control headers (so no FilesMatch as it was for all files).
Here is an example of what I'm now doing for my work-around (in the same format as the above examples):
# Set the cache headers as desired for individual files
<FilesMatch "png">
Header set Cache-Control "max-age=123, public"
</FilesMatch>
# When this condition is true unset all of the caches (to be replaced with a query string detection)
<If true>
# Notice no FilesMatch here– it affects all files
Header unset Cache-Control
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</If>
Again, this does not actually answer the core question, so I am not going to "accept" my own answer, but I wanted to provide it for anyone else.
You may be able to use if/else
for .png
files like this:
<FilesMatch "\.png$">
<If false>
Header unset Cache-Control
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</If>
<Else>
Header set Cache-Control "max-age=31536000, public"
</Else>
</FilesMatch>
Expectedly it will set Cache-Control: max-age=31536000, public
for all .png
files.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.