Browser language based 404 pages with mod_rewrite

2019-02-25 07:10发布

问题:

I am trying to generate language dependant 404 (also other errors) pages purely based on Apache mod_rewrite rules by evaluating the clients HTTP Accept-Language header. I've managed to show the correct pages (english default) with this rules:

RewriteEngine on
RewriteBase / 
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{HTTP:Accept-Language} ^es [NC]
RewriteRule (.+) /esp/error404.php [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule (.+) /eng/error404.php [L]

My problem is that I would like to maintain 404 errors and I understand redirect does not allow this type of flag. I am in any case not 100% sure if it's really worth SEO wise as it might be better not to have 404s at all, but I thought that it would be more logical and maintain logs consistent, etc, but I simply can't figure how to achieve that via apache and HTTP:Accept-Language.

Any comments would be mostly appreciated.

回答1:

You could use Apache's default error handler to do this.

It should be possible to define an ErrorDocument like so:

ErrorDocument 404 /parseme.php

and then do a language-dependent redirect for requests to /parseme.php like so:

RewriteCond %{REQUEST_FILENAME} ^/parseme\.php$
RewriteCond %{HTTP:Accept-Language} ^es [NC]
RewriteRule (.+) /esp/error404.php [L]

RewriteCond %{REQUEST_FILENAME} ^/parseme\.php$
RewriteCond %{HTTP:Accept-Language} ^eng [NC]
RewriteRule (.+) /eng/error404.php [L]

I have never tried this but this should give you a 404 header, and the error page in the correct language, too.



回答2:

Previous answer from Pekka did the job. I include full code here for reference as it does not fit in comments.

I never assumed that even the 404 document directive could be rewrited. Just to clarify for anyone else... the "parseme.php" file does not even need to exists as it should be redirected to via rewrite. Not sure but it seemed to work in my case only when directives were at virtualhost root rather than top directory. Final code working for me as follows:

ErrorDocument 404 /error_404.php

RewriteEngine on
# If spanish... use spanish error page
RewriteCond %{REQUEST_FILENAME} ^/error_404\.php$
RewriteCond %{HTTP:Accept-Language} ^es [NC]
RewriteRule (.+) /esp/error404.php [L]

# If previous did not match - any language (note [L] flag on previous rule) use english
RewriteCond %{REQUEST_FILENAME} ^/error_404\.php$
RewriteRule (.+) /eng/error404.php [L]


回答3:

You cannot interpret the Accept-Language header field like you do. It’s not just a single value but a list of weighted values.

You should better do the language negotiation with PHP as mod_rewrite is too limited for that.