Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Apache mod_重写重定向循环(干净URL)_Apache_.htaccess_Mod Rewrite_Url Rewriting - Fatal编程技术网

使用Apache mod_重写重定向循环(干净URL)

使用Apache mod_重写重定向循环(干净URL),apache,.htaccess,mod-rewrite,url-rewriting,Apache,.htaccess,Mod Rewrite,Url Rewriting,我的情况与中的非常相似(事实上,代码非常相似)。我一直在尝试创建一个.htaccess文件,以使用不带文件扩展名的URL,例如https://example.com/file在适当的目录中查找file.html,但也查找https://example.com/file.html重定向(使用HTTP重定向)到https://example.com/file因此只有一个规范URL。使用以下.htaccess: Options +MultiViews RewriteEngine On # Redir

我的情况与中的非常相似(事实上,代码非常相似)。我一直在尝试创建一个
.htaccess
文件,以使用不带文件扩展名的URL,例如
https://example.com/file
在适当的目录中查找
file.html
,但也查找
https://example.com/file.html
重定向(使用HTTP重定向)到<代码>https://example.com/file因此只有一个规范URL。使用以下
.htaccess

Options +MultiViews
RewriteEngine On

# Redirect <...>.php, <...>.html to <...> (without file extension)
RewriteRule ^(.+)\.(php|html)$ /$1 [L,R]
没有重定向循环。我很想知道差异的来源。这两个文件不是功能相同吗?为什么使用“普通的”
RewriteRule
会创建一个循环,而使用
%{THE_REQUEST}
不会

请注意,我不是在寻找一种获得干净URL的方法(我可以使用我的文件的第二个版本或上面链接的问题的答案,它查看
%{ENV:REDIRECT_STATUS}
),但是出于原因为什么这两种方法有效/无效,因此,这与上面链接的问题不同

注意:我发现仅使用mod_rewrite(无
多视图
)会出现同样的问题,因此这似乎不是由于
多视图
和mod_rewrite的执行顺序造成的:

Options -MultiViews
RewriteEngine On

## Redirect <...>.php, <...>.html to <...> (without file extension)
# This works...
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.+)\.(php|html)
RewriteRule ^ %1 [L,R]
# But this doesn’t!
#RewriteRule ^(.+)\.(php|html)$ /$1 [L,R]

# Find file with file extension .php or .html on the filesystem for a URL
# without file extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^ %{REQUEST_FILENAME}.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^ %{REQUEST_FILENAME}.html [L]
选项-多视图
重新启动发动机
##将.php、.html重定向到(不带文件扩展名)
#这很有效。。。
重写cond%{THE_REQUEST}^[A-Z]{3,}\s(+.+)\(php | html)
重写规则^1[L,R]
#但事实并非如此!
#重写规则^(+)\(php| html)$/$1[L,R]
#在文件系统上查找文件扩展名为.php或.html的文件以获取URL
#没有文件扩展名
重写cond%{REQUEST_FILENAME}-D
重写cond%{REQUEST_FILENAME}-F
重写cond%{REQUEST_FILENAME}\.php-f
重写规则^%{REQUEST_FILENAME}.php[L]
重写cond%{REQUEST_FILENAME}-D
重写cond%{REQUEST_FILENAME}-F
重写cond%{REQUEST_FILENAME}\.html-f
重写规则^%{REQUEST_FILENAME}.html[L]
区别在哪里?我希望这两种方法都能起作用,因为对文件的内部重写在
.htaccess
的末尾,带有
[L]
标志,所以之后不应该发生任何处理或重定向,对吗

# But this doesn’t!
#RewriteRule ^(.+)\.(php|html)$ /$1 [L,R]
此注释规则不起作用并导致重写循环的原因,因为您的其他规则正在添加
.html
扩展名,并将
%{REQUEST\u URI}
变量更改为
/file.html
,从而导致此规则再次执行。从规则中取出
.html
,会导致其他规则再次触发。直到达到最大递归限制为止

您还需要了解,
mod_rewrite
在循环中运行,直到规则不匹配为止。由于这两条规则都会不断触发,因此,
mod_rewrite
会不断循环

基于的规则之所以有效,是因为执行其他重写规则后,
请求
变量没有被覆盖。

如果查看,您会注意到以下几点:

RewriteRule ^(.+)\.(php|html)$ /$1 [L,R]
在第一个
重写规则
,它与(%-解码)匹配 请求的URL路径,或者,在每个目录上下文中(请参见下文) 相对于每个目录上下文的URL路径。后续模式 与上次匹配的
重写规则的输出相匹配

因为,一旦您输入以下内容,它将在每个目录的基础上进行匹配:

RewriteRule ^(.+)\.(php|html)$ /$1 [L,R]
REQUEST\u URI
变量改变,mod rewrite再次解析URI。这将导致
MultiViews
将URL重写为与此重定向URL匹配的正确文件,并导致循环(每次重写时URI都会更改)


现在,当您放置
要匹配的\u REQUEST
变量时,URI可能会在内部重写时更改,但是服务器收到的实际请求将永远不会更改,除非执行重定向。

但是
[L]
标记不应该停止mod\u rewrite循环吗?为什么它仍然在执行例如
RewriteRule^%{REQUEST_FILENAME}.html[L]
?No
L
标志不会停止循环
L
标志仅结束当前规则并强制
mod_rewrite
再次运行循环。您所说的“当前规则”是指“当前通过
.htaccess
文件”吗?否则,该标志将是无用的…是的,这是当前的。它结束当前使用的
重写规则
,然后充当mod_rewrite循环的
continue
。另外请注意,如果您使用
END
(Apache 2.4+提供),那么肯定会终止
mod\u rewrite
循环。这里的问题与另一个答案相同:
[L]
标记不应该停止mod\u rewrite循环(在我的上一个示例中)?为什么它仍然继续执行例如
RewriteRule^%{REQUEST_FILENAME}.html[L]
?即使其他规则仍然匹配,难道它不应该停在
[L]
吗?@Socob的has:“因此,如果您在这些上下文中使用
重写规则
指令,那么您必须采取明确的步骤来避免规则循环,而不仅仅依赖
[L]
标记终止一系列规则的执行,如下所示。”。是的,我知道文档的这一部分。我想理解的是为什么
[L]
在这种情况下对我没有帮助。是因为以下的原因吗?在处理重写请求时,可能会再次遇到
.htaccess
文件或
部分,因此规则集可能会从一开始就再次运行。最常见的情况是,如果其中一个规则导致重定向(内部或外部)导致请求过程重新开始,则会发生这种情况@Socob啊,是的。我在上一条评论中粘贴文本时删除了错误的段落。@Socob Once
L
标志为encoun