1

I want to redirect all traffic on my webpage from www to non-www. So every request that goes to www.example.com will be redirected to example.com.

This is done in my .htaccess (taken from this question)

RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

The problem is, that I previously didn't have this rule in my .htaccess file. So if a user previously accessed the website using www.example.com now the cache seems to prevent the redirect to example.com and instead the www URL stays in the address bar.

If I however open a private browser window or clear the website data, the redirect works as expected.

I've tested it in both Chrome (88.0.4324.192) and Firefox (86.0), both browsers show the same behavior. OS: macOS 10.15.7

How can I fix this from a server-side perspective? Since I can't tell all users to clear their cache.

Steps to reproduce:

  1. Clear cache and history in browser to start with a clean session
  2. Open www.example.com
  3. Add rewrite rule www to non-www in .htaccess file
  4. Open www.example.com again (browser should have this address in his history from the last access). No rewrite to example.com will happen.


EDIT: Maybe this occurs, because the browser has content already cached for www.example.com and thus doesn't even request the server. However the problem remains the same.

Codey
  • 1,131
  • 2
  • 15
  • 34
  • `No rewrite to example.com will happen` Cannot reproduce this. Do you have some proxy or cache plugin? – anubhava Mar 07 '21 at 11:09
  • @anubhava not that I know of. I don't use Chrome or Firefox as my personal browser only for testing. So they are a clean install without any extras, no plugins. A colleague using Firefox could reproduce this issue. I've added the browser versions I used in the question. I think it is also important, that `www.example.com` is in the browser history and `example.com` is not. – Codey Mar 07 '21 at 11:12
  • It might well be that some clients use a cached version and do not immediately follow your redirection. That has nothing to do with that rewrite rule, though. Instead the content in the cache dates from the time _before_ that redirection rule. So only new clients will see that rule or clients with expired or deleted cache content. – arkascha Mar 08 '21 at 08:41
  • So you mean there is no way to force using this new redirect rule for existing clients? – Codey Mar 08 '21 at 10:19

2 Answers2

2

If their computers have already cached the website, it will be really difficult. in fact impossible to force a refresh since am assuming you did not put that in your code.

What you could do now is include a rule in your code that will force a periodic cache clearing. This way, your future updates will not face this same issue.

Or you could also completely disable caching which is not exactly ideal but it's up to you and the design you have

--in HTML

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

--in .htaccess

<IfModule mod_headers.c>
  Header set Cache-Control "no-cache, no-store, must-revalidate"
  Header set Pragma "no-cache"
  Header set Expires 0
</IfModule>

Find other options for other languages from this link;

Another overkill solution is;

If there is anything on your website that does a database check and the result loads a new page, for instance a user session check or login; you could take advantage of that by modifying their database records in such a way that they will be forced to the login page. which will force them to reload when they get there and when they are forced to reload, their data is restored.

It's a last resort but if the world depended on it sure, else. relax with the first solution. people will not keep the cache forever.

UPDATE

As I said in my previous response, you could set periodic caching in your next release. This can be simply done in HTML.

Cache-Control : public, max-age=3600;

Cache-Control : private, max-age=3600;

The differences between the 2 codes above are the public and private which indicates whether anyone (public) or just the end user (private) can cache up to the max-age (time in seconds).

But this can also be done explicitly in several other languages. Here is an example in PHP

<?php
 Header("Cache-Control: must-revalidate");

 $offset = 60 * 60 * 24 * 3;
 $ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
 Header($ExpStr);
?>

Here are some links that could assist you have a better understanding of how that works.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
mw509
  • 1,957
  • 1
  • 19
  • 25
  • "include a rule in your code that will force a periodic cache clearing" - how do you do that? – MrWhite Mar 08 '21 at 16:47
  • I'm not the OP, but _in principle_ how do you do that, regardless of scripting language? Like you said in the first sentence, it's "impossible to force a refresh", so I'm curious what you mean by "periodic cache clearing"? – MrWhite Mar 08 '21 at 20:14
  • Thank you for the detailed response, I think I will try to prevent these types of caching issues by implementing the html cache control, not with no cache at all, but with a time limit. – Codey Mar 09 '21 at 17:09
  • @MrWhite I think what he means is that I cannot force a refresh after the page is already cached. But for future caching, I can implement something, that will periodically trigger refreshing the cache. I guess this could be done in HTML with those `http-equiv` meta tags? (the answer includes an example how to completely turn of caching, but not how to configure caching duration) – Codey Mar 09 '21 at 17:13
  • I have updated my answer with examples for managing caching durations/periodic caching. – mw509 Mar 10 '21 at 08:23
0

In place of using 301 response code, you can consider using 302 or 307, which is for Temporary redirect. Link

The response is not cached by default, unless indicated.

Uday Shankar
  • 438
  • 1
  • 3
  • 16