如何停止.htaccess循环

时间:2012-12-12 03:50:59

标签: apache .htaccess mod-rewrite

我不是htaccess文件的专家,我正在尝试一些看似非常简单的东西,但我无法做到。

我搜索并最终发现这里的东西可以用于我的使用,但事实并非如此。代码如下。

这是我需要的一个例子:

http://localhost/Test/TestScript.php显示:http://localhost/Test/TestScript/脚本位于原始位置。

这些是我的规则(已复制):

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]

这条规则给出:

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

因此将最后一行更改为:

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

但现在得到这个错误:

The page isn't redirecting properly

希望这个地方的优秀人才能帮助我。谢谢。

3 个答案:

答案 0 :(得分:7)

规则集以循环结束。我们来看看:

请求http://localhost/Test/TestScript.php被重定向到http://localhost/Test/TestScript/,供浏览器显示,最后尝试映射回原始资源。

规则中的[L]标志并没有像许多人想的那样停止这个过程。重写引擎循环遍历完整的规则集,逐个规则,当特定规则匹配时,它循环通过相应的条件(如果有的话)。由于对每个请求重复此过程并且规则生成新请求,因此很容易进入无限循环。

在这种情况下,“页面未正确重定向”的消息就是这样。

以下是此过程的The Technical Details

一些解决方案:

I)最好也更实用的是在初始请求中直接使用“漂亮”URL,将其静默映射到资源。这是一个单步过程,其中“漂亮”URL始终显示在浏览器的地址栏中。此选项的一个优点是传入URL的URI路径中的任何内容都不存在

  1. 请求:http://localhost/Test/TestScript/
  2. 内部映射到资源:http://localhost/Test/TestScript.php
  3. 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)如果这是不可能的,因为已经存在直接指向资源的链接,显示“漂亮”URL但仍然从原始请求获取数据的一种方法是制作首先是可见和永久重定向,剥离扩展以显示“漂亮”URL,然后内部重写回原始资源。

    1. 请求:http://localhost/Test/TestScript.php
    2. 永久和可见重定向到:http://localhost/Test/TestScript/“漂亮”网址
    3. 内部和静音映射回:http://localhost/Test/TestScript.php,原始请求。
    4. 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]
      

      备注:

      1. 以上选项将放在根目录下的一个.htaccess文件中,确保启用mod_rewrite
      2. 字符串测试 TestScript 被认为是动态的,可以用任何名称替换。
      3. 主机名 localhost 是一个示例,也可以替换为任何其他名称。

答案 1 :(得分:0)

最有可能的循环是由于.htaccess处理中的怪癖,而不是你编码的任何东西。 (奇怪的是,一个简单的.htaccess与 out 一个循环比一个循环更令人惊讶:-)如果它循环,不要立即假设你有一些某种逻辑错误或错误编码的东西。

在.htaccess规则中(与httpd.conf中的相同规则不同),[L] ast标志从顶部开始。 (参见启用的循环可能性? - )

一些典型的解决方案(除了上面列出的解决方案之外)是:

选项1:在您确实打算从该子目录中的.htaccess文件中完全立即退出的行上使用[END]标志而不是[L] ast标志。 (问题是,[END]标志仅在较新的[版本2.3.9及更高版本] Apaches中可用,并且在早期版本中甚至没有"后退"。

选项2:在每个.htaccess文件的顶部添加这样的样板代码:

string[] files = File.ReadAllLines(userVideosDirectory + "\\UploadedVideoFiles.txt").Skip(1).ToArray();
File.WriteAllLines(userVideosDirectory + "\\UploadedVideoFiles.txt", files);

答案 2 :(得分:-2)

我不是.htaccess的专家,但你不需要在某个时候重定向吗?

例如:重定向http://www.yoursite.com/test/testscript/

我再也不是专家。但也许可以尝试查看:http://forums.techguy.org/web-design-development/717997-solved-htaccess-redirect-loop-problem.html