Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
733 views
in Technique[技术] by (71.8m points)

apache - How to stop .htaccess loop

I am not expert in htaccess files and I am trying something that seems very simple but I have not been able to do it.

I searched and finally find something here could work for my use but it didn't. The code is below.

Here is an example of what i need:

http://localhost/Test/TestScript.php to show this: http://localhost/Test/TestScript/ with script in original place.

These are my rules (Copied):

Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /Test

## hide .php extension
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}s([^.]+).php [NC]
RewriteRule ^ %1 [R,L,NC]

## To internally forward /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_FILENAME}.php [L]

This rule give:

Forbidden You don't have permission to access ".../Test/TestScript.php on this server."

So changed last line to:

RewriteRule ^.*  http://localhost/Test/TestScript.php  [L]

But now get this error:

The page isn't redirecting properly

Hope brilliant people in this place can help me. Thank you.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The rule-set ends up in a loop. Let's see:

The request is http://localhost/Test/TestScript.php is redirected to http://localhost/Test/TestScript/, for the browser to show it, and finally is trying to be mapped back to the original resource.

The [L] flag in the rule doesn't stop the process, as many people think. The rewriting engine loops through the complete rule-set, rule by rule, and when a particular rule matches, it loops through the corresponding conditions, if any. As this process is repeated for each request and rules generate new requests, it is easy to enter an infinite loop.

That's what the message "The page isn't redirecting properly" means in this case.

Here are The Technical Details of this process

Some solutions:

I) The best and more practical one is to use directly the "pretty" URL in the initial request, mapping it silently to the resource. This is a one step process where the "pretty" URL is always displayed in the browser's address bar. One of the advantages of this option, is that nothing in the URI-path of the incoming URL has to exist.

  1. Request: http://localhost/Test/TestScript/
  2. Mapped internally to resource: http://localhost/Test/TestScript.php
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
# Prevent loops
RewriteCond %{REQUEST_URI} !.php  [NC]
# Map internally to the resource, showing the "pretty" URL in the address bar
RewriteRule  ^([^/]+)/([^/]+)/?   /$1/$2.php  [L,NC]

II) If that's not possible because there are already links pointing directly to the resource, one way to show the "pretty" URL but still get the data from the original request, is to make a visible and permanent redirect first, stripping the extension to display the "pretty" URL, and then an internal rewrite back to the original resource.

  1. Request: http://localhost/Test/TestScript.php,
  2. Permanent and visible redirect to: http://localhost/Test/TestScript/ the "pretty" URL,
  3. Internal and silent mapping back to: http://localhost/Test/TestScript.php, the original request.
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /

# Get the URI-path directly from THE_REQUEST variable
RewriteCond %{THE_REQUEST} ^(GET|HEAD)s/([^/]+)/([^.]+).php [NC]
# Strip the extension and redirect permanently
RewriteRule  .*   /%2/%3/   [R=301,L,NC]

# Now the browser bar shows `http://localhost/Test/TestScript/`

# Prevent loops
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.php  [NC]
# Map internally to the original resource
RewriteRule  ^([^/]+)/([^/]+)/?   /$1/$2.php  [L,NC]

NOTES:

  1. The above options are to be placed in one .htaccess file at root directory, making sure mod_rewrite is enabled.
  2. Strings Test and TestScript are assumed to be dynamic and can be replaced with any name.
  3. Host name localhost is an example and can also be replaced with any other name.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...