Can 2 .htaccess files block URL rewriting

2019-09-21 10:34发布

问题:

I have a codeigniter project inside the b1 folder in my public_html folder:

mydomain.com/b1/controller/function

I want to change it to:

mydomain.com/controller/function

in the browser bar using a 301 redirect.

My .htaccess file in my public_html has:

RewriteEngine on
RewriteRule ^b1/(.*)$ /$1 [R=301,L,NC] 
RewriteRule ^(.*)$ b1/$1

EXPLANATION:

RewriteRule ^b1/(.*)$ /$1 [R=301,L,NC] # THIS IS TO REWRITE ALL REQUESTS FROM THE NAVBAR IN MY PROJECT WHICH HAVE THE FORM mydomain.com/b1/controller/function TO mydomain.com/controller/function. AFTER THIS THE NAVBAR SHOULD SHOW mydomain.com/controller/function ( I ASSUME )

RewriteRule ^(.*)$ b1/$1 # THIS IS TO TAKE ALL INCOMING REQUESTS AND ADD A b1 IN FRONT SO  mydomain.com/controller/function IS REDIRECTED TO  mydomain.com/b1/controller/function - BUT INTERNALLY, SO THAT THE BROWSERS ADDRESS BAR STILL SHOWS A 'PRETTIER'  mydomain.com/controller/function

According to http://htaccess.madewithlove.be/, this should work, but I still see:

mydomain.com/b1/controller/function

in my address bar.

Please note that this is a codeigniter project and CI has the following .htaccess file . ( again the project is in my public_html/b1 directory )

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php/$0 [PT,L]

As far as I can tell mod_rewrite is working because RewriteRule ^(.*)$ b1/$1 works when a match to the rule above it does not occur.

Could some combination of the 2 .htaccess files be causing the lack of visible rerwrite in the address bar? I would like to debug this and figure out how to achieve the URL format discussed above.

Thank you,

Bill

addendum: thanks to everybody for their attempts. what I notice about multiple answers though is that:

RewriteRule ^b1/(.*)$ /$1 [R=301,L,NC] 
RewriteRule ^(.*)$ b1/$1 [L]

Their seem to be a lot of L flags . In pseudocode what I want to achieve is:

IF REQUEST is mydomain.com or www.mydomain.com ( with nothing after the /) rewrite to mydomain.com . FIRST REWRITE TO REMOVE B1 IF EXISTS ( this is for the navbar requests which have form: mydomain.com/b1/controller/function which should be rewritten to mydomain.com/controller/function ) so that the address bar shows mydomain.com/controller/function 

if theres an L above , I don't think it will work

Then add b1 back in internally so you redirect to b1 folder where project is stored

回答1:

Your problem is with the two .htaccess files your are using. When using .htaccess it will use the file that is closest to the requested folder. In your case you have the following folder structure

- public_html
  - B1
    - .htaccess  //from codeigniter project
  .htaccess //your own with redirect

So when you call the url mydomain.com/b1/controller/function the closest .htaccess it can find is the codeigniter one, so it will use this one. Your own file will not be used. In other words your redirect rules are never even evaluated.

Now if you call mydomain.com/controller/function the closest .htaccess, is your own and the request is redirected to mydomain.com/b1/controller/function as expected. There it will again try to find the closest .htaccess which is the codeigniter one and thus the request works.

There are two things you can do. The first and best thing is to remove your .htaccess and copy all files and folders from the b1 folder back to your public_html folder and then simply remove the b1 folder. This way your server doesnt even have a b1 folder and everything will work as expected.

The second option would be to combine the two .htaccess files and keep them in your public_html folder. Make sure you delete the one in the b1 folder. The file would look something like

RewriteEngine on

RewriteRule ^b1/(.*)$ /$1 [R=301,L,NC] 

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


回答2:

My attempt:

RewriteEngine on
RewriteBase /

RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule ^b1/(.*)$ /$1 [R=301,L,NC]

RewriteRule ^(.*)$ b1/$1 [L]


回答3:

For 301 redirect use Redirect in .htaccess file:

Redirect 301 /redirect_from http://www.mydomain.com/redirect_to


回答4:

Why you are using it in a b1 sub-folder when you want it to function as a main project in a domain ?



回答5:

The simplest way to achieve what you're trying to do would be to move Codeigniter's index.php file into your public_html/ folder and update the $system_folder and $application_folder paths to point to your b1/ folder. Example below:

/public_html/index.php

/*
 *---------------------------------------------------------------
 * SYSTEM FOLDER NAME
 *---------------------------------------------------------------
 *
 * This variable must contain the name of your "system" folder.
 * Include the path if the folder is not in the same  directory
 * as this file.
 *
 */
$system_path = 'b1/system';

/*
 *---------------------------------------------------------------
 * APPLICATION FOLDER NAME
 *---------------------------------------------------------------
 *
 * If you want this front controller to use a different "application"
 * folder then the default one you can set its name here. The folder
 * can also be renamed or relocated anywhere on your server.  If
 * you do, use a full server path. For more info please see the user guide:
 * http://codeigniter.com/user_guide/general/managing_apps.html
 *
 * NO TRAILING SLASH!
 *
 */
$application_folder = 'b1/application';

This will 'internally' tell Codeigniter that all your application stuff is in the b1/ folder, but from an end-user perspective your domains will still look like mydomain.com/controller/function

Your .htaccess file will then look like this:

/public_html/.htaccess

RewriteEngine on
RewriteBase /

# redirect any actual requests for your b1 folder
# back to the web root
RewriteRule ^b1/(.*)$ /$1 [R=301,L,NC]

# remove index.php from the url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1

You shouldn't then have any need for a .htaccess file in the b1 folder.