简体   繁体   中英

Cache-Control headers inside <If> and <Else> conditionals are being ignored in htaccess file

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.

Test cases

I made a webpage that simply loads a single image.png file and I read the Cache-Control header in Chrome DevTools.


Example A

.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

最大年龄为 123


Example B

.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM