Search code examples
apache.htaccesshttp-redirectmod-rewriteurl-rewriting

How to redirect a url that ends with html to https non-www version, while also retrieve the content from a specific php files?


i am still new to htaccess. I have a static website, that has a content inside several directories. I use this to redirect 301 all html pages to its https non-www version.

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule (.*) https://example.com/$1 [L,R=301]

I want the website to be dynamic. So after it redirects to https non-www version, i want it to grab the resources from a specific php files. But, i don't know how to do that, while also do the first 301 redirect.

I try to grab the resources by using something like:

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule (.*) https://example.com/$1
RewriteRule (.*)/(.*)/(.*)\.html$ https://note.mathpro.id/$2.php?name=$3 [L,R=302]

This URL http://example.com/category/uncategorized.html retrieves the content from https://example.com/category.php?name=uncategorized, but doesn't redirect it to https://example.com/category/uncategorized.html as it intially did.

Can anyone help?


Solution

  • ... i don't know how to do that, while also do the first 301 redirect.

    These are two entirely separate tasks that requires two different rules. You should not modify the first (canonical redirect) rule. (For some reason, you have removed the flags argument, ie. [L,R=301] - The L flag is required for the redirect to function as intended.)

    RewriteRule (.*)/(.*)/(.*)\.html$ https://note.mathpro.id/$2.php?name=$3 [L,R=302]
    

    This should not be an external redirect, it should be an internal rewrite. In order words, you want the (visible) URL to remain as /category/uncategorized.html. You don't want the end user to see /category.php?name=uncategorized.

    For some reason you also have three capturing subpatterns in the RewriteRule pattern (.*)/(.*)/(.*)\.html$, whereas your example URL /category/uncategorized.html only has two?

    Your regex should also be more restrictive. The "problem" with the very generic .* is that it is "greedy" and consumes everything, including slashes. So this regex will also match /foo/bar/baz/zip/bah/yop.html. (But which parts will it match/capture exactly?)

    Try the following instead:

    # 1. Canonical redirect (UNCHANGED)
    RewriteCond %{HTTPS} off [OR]
    RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
    RewriteRule (.*) https://example.com/$1 [L,R=301]
    
    # 2. Rewrite to handler
    RewriteRule ^([^/]+)/([^/]+)\.html$ $1.php?name=$2 [L]
    

    This assumes the .htaccess file is located in the document root.

    However, a minor problem with the above rewrite is that it rewrites the URL regardless of whether the "handler" (eg. category.php) exists or not. This isn't necessarily a big deal, but it means the 404 is triggered on category.php (the rewritten file-path), not /category/uncategorized.html (the originally requested URL from the user).

    To resolve this, you can check whether the target file exists first. For example:

    # 2. Rewrite to handler if it exists
    RewriteCond %{DOCUMENT_ROOT}/$1.php -f
    RewriteRule ^([^/]+)/([^/]+)\.html$ $1.php?name=$2 [L]