简体   繁体   中英

.htaccess - rewrite a URL and also display content from another source

I'm trying to figure out how to combine rewriting and redirecting URLs with .htaccess . My specific example is: initially I wanted to remove file extensions from page URLs, so I set this up to make /page display the content of /page.php :

# URLs without file extension lead to the file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]

But then I found that if a trailing slash is mistakenly added, it will still cause an error - ie /page/ doesn't work. I'd like someone to be able to navigate to /page/ (because if it gives a 404, that really suggests that /page doesn't exist, even though it does) - but I also want to rewrite their URL to remove the slash so the mistake doesn't happen again.

So, I want two things to happen when someone navigates to /page/ .

  1. The URL is rewritten to /page .
  2. The page loads content from /page.php .

While also keeping the rule that navigating to /page itself will load /page.php .

Is there a way to combine this behaviour into one rewrite rule? If not, how do I make it happen with two separate rules and prevent feedback loops?

The “problem” here is this check,

RewriteCond %{REQUEST_FILENAME}\.php -f

If page/ was requested, you will have to cut off that trailing slash here, before you append .php and check if that's an existing file. But that's not that easy to do when you only have %{REQUEST_FILENAME} available, and not much in terms of “string functions” …

But, the RewriteRule is evaluated first anyway, so you can achieve this by matching what comes before an (optional) trailing slash inside the rule first, and then use the back reference this creates inside the condition to perform this check:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1.php -f
RewriteRule ^(.*)/?$ $1.php [NC,L]

So far for the theory, not tested in practice ;-) Not too sure whether checking for an existing file works with a relative path only - otherwise, you might have to prefix that with a different variable such as maybe the DOCUMENT_ROOT.

Might be that you need to be a bit more specific in what your rule is allowed to match also, because right now it would allow for something like folder/page as well, not sure whether you want to handle that the same way or not.

Solved! I added this rule to remove the trailing slash from URLs which aren't directories, before the file extension rule.

# Non-directory URLs with trailing slash change to without
RewriteCond %{REQUEST_URI} ^(.*)/$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ https://%{HTTP_HOST}%1 [R,L]

The line in Dusan Bajic's comment didn't work on its own - it rewrote the address with the absolute file path instead of the original URL path. But it did find the slash correctly, so I rewrote the substitution to explicitly give the correct address minus the slash.

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