问题
Using htaccess I want to force http to https and at the same time redirect to www. and to the 'public' folder where my application files are.
The result should be that http://example.com
should redirect to https://www.example.com/public/
To redirect to https and www I manage by using:
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [L,NE,R=301]
To redirect to the 'public' folder I manage by using:
ReWriteCond %{REQUEST_URI} !^public/
ReWriteRule ^(.*)$ public/$1 [L]
Now I need to combine these but my many attempts did not result in a working redirect and I would need some advise on this.
EDIT: In the folder public is another htaccess file:
SetEnv APPLICATION_ENV "production"
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]
<<
回答1:
ReWriteCond %{REQUEST_URI} !^public/ ReWriteRule ^(.*)$ public/$1 [L]
The REQUEST_URI
server variable starts with a slash, so the condition above will never match. For example:
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule (.*) public/$1 [L]
However, assuming you have another .htaccess
file in the /public
subdirectory I would write this block like the following instead:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) public/$1 [L]
This has the added benefit of allowing a public
path segment at the start of your URLs (if you wish). eg. The URL /public/foo
would internally rewrite to /public/public/foo
without creating a rewrite loop.
RewriteCond %{HTTPS} off RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC] RewriteRule ^ https://www.%1%{REQUEST_URI} [L,NE,R=301]
You are missing an OR
flag on the first condition. For example:
RewriteCond %{HTTPS} off [OR]
:
Without that, it will fail to redirect http://www.example.com/
to HTTPS.
Just to clarify, the canonical redirect should go before the internal rewrite to the public
directory.
UPDATE:
EDIT: In the folder public is another htaccess file:
SetEnv APPLICATION_ENV "production" RewriteEngine On RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^.*$ /index.php [NC,L]
The substitution string on the last RewriteRule
directive is incorrect. You need to remove the slash prefix from /index.php
. It should just read index.php
. Otherwise it is going to rewrite the request back to the document root (filesystem path) and result in either an endless loop or a 404 (depending on the parent directives). By changing it to index.php
(no slash) it is now relative to the /public
directory (the directory that contains the .htaccess
file), instead of the document root.
You can also simplify the RewriteRule
pattern and the NC
flag is not required here. So, in summary, the /public/.htaccess
file should read:
SetEnv APPLICATION_ENV "production"
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^ index.php [L]
来源:https://stackoverflow.com/questions/59937631/redirect-in-htaccess-to-folder-and-https