Apache 如果不存在重写后添加正斜杠

Apache 如果不存在重写后添加正斜杠,apache,.htaccess,mod-rewrite,Apache,.htaccess,Mod Rewrite,我读了很多书,尝试了很多解决方案,但找不到适合我需要的解决方案 在我的htaccess中,我有以下内容: RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^profile/([\w-]+)/?$ profile.php?username=$1 [L,QSA] RewriteRule ^profile/([\w-]+)/([\w-]+)/?$ profile.php?userna

我读了很多书,尝试了很多解决方案,但找不到适合我需要的解决方案

在我的htaccess中,我有以下内容:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^profile/([\w-]+)/?$ profile.php?username=$1 [L,QSA]
RewriteRule ^profile/([\w-]+)/([\w-]+)/?$ profile.php?username=$1&type=$2 [L,QSA]
RewriteRule ^profile/([\w-]+)/([\w-]+)/([\w-]+)/?$ profile.php?username=$1&type=$2&o=$3 [L,QSA]
RewriteRule ^profile/([\w-]+)/$ profile.php?username=$1 [L,QSA]
除了一个小问题外,这个方法工作得非常好

如果
profile/username
没有
/
,除非使用绝对URL,否则页面上的链接将中断。因此
将以
profile/1
而不是
profile/username/1

如果我将第一次重写更改为以下内容:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^profile/([\w-]+)/?$ profile.php?username=$1 [L,QSA]
RewriteRule ^profile/([\w-]+)/([\w-]+)/?$ profile.php?username=$1&type=$2 [L,QSA]
RewriteRule ^profile/([\w-]+)/([\w-]+)/([\w-]+)/?$ profile.php?username=$1&type=$2&o=$3 [L,QSA]
RewriteRule ^profile/([\w-]+)/$ profile.php?username=$1 [L,QSA]
然后
https://myurl/username
将返回一个我不想要的404,如果它不存在,我希望它在末尾强制/

我尝试补充:

RewriteRule ^(.*)([^/])$ /$1$2/ [L,R=301] 
我试过了

RewriteRule ^(.*)$ https://nmyurl/$1/ [L,R=301]

只是想不出在重写条件已经存在的情况下如何实现这一点。

要在
配置文件的末尾添加可选跟踪,您可以使用此选项

RewriteEngine on

RewriteCond %{REQUEST_URI} ^/profile/
RewriteRule !/$ %{REQUEST_URI}/ [L,R]
如果
profile/username
没有
/
,除非使用绝对URL,否则页面上的链接将中断。因此
将以
profile/1
而不是
profile/username/1

如果这个问题只适用于
/profile/
格式的URL,那么我将是特定的,并且只在这些特定URL后面附加斜杠,否则,您将得到大量重定向(这可能对SEO有害)

但是,您应该确保内部链接是针对规范URL的(即带有尾随斜杠)

例如,在现有重写之前,应执行以下操作:

RewriteRule ^(profile/[\w-]+)$ /$1/ [R=301,L]
由于规范URL需要尾部斜杠,因此这应该是301(永久)重定向。(但先用302进行测试。)


或者,不必在
.htaccess
中重定向(如果您仍然在内部链接到无斜杠的URL),您可以向
标题
部分添加
基本
元素(包括尾部斜杠),以说明相对URL应该是相对于什么的

例如:

<base href="/profile/<username>/">

这两个
RewriteCond
指令似乎是完全多余的
RewriteCond
指令仅适用于后面的第一条
RewriteRule
。但是
重写规则
模式无论如何都不可能与真实文件匹配(除非您的文件没有扩展名或同名目录)。

因此,不幸的是,我无法实现我希望的目标,因为可能存在或不存在多个级别的变量

在第一部分中,使用了Amit提供的解决方案:

RewriteCond %{REQUEST_URI} ^/profile/
RewriteRule !/$ %{REQUEST_URI}/ [L,R]
然而,这还不够,因为正如怀特先生所指出的,有3个单独的潜在url

https://myurl/profile/username/
https://myurl/profile/username/type/
https://myurl/profile/username/type/o/
在此情况下,用户名应始终存在,但类型和o可能存在,也可能不存在

所以我做的是检测url的级别,然后创建条件。和。。使用php

变量o总是数字的,变量类型从来都不是数字的,所以这对我来说很有用

if (isset($_GET['o'])) { $o = strip_tags($_GET['o']); }
elseif (isset($_GET['type']) && is_numeric($_GET['type'])) { $o = strip_tags($_GET['type']); }
然后我发现:

// if o is set or if type is numberic, use ..
if (isset($_GET['o']) || (isset($_GET['type']) && is_numeric($_GET['type']))) {
  $dots = '..';
// if o is not set and type is not numeric just use .
} else {
  $dots = '.';
}
的最终结果:


这是理想的结果。

应该有一个/after profile
RewriteCond%{REQUEST\u URI}^/profile/
否则它将重定向到
profile.php/?username=username
@Bruce是的,你是对的。我已经根据你的建议更新了代码。谢谢。重写工作完全符合我的意图。第一个允许
/profile/username/
,实际上是
profile.php?username=username
。第二个允许
/profile/username/type/
,实际上是
profile.php?username=username&type=type
。第三个允许
/profile/username/type/12/
,实际上是
profile.php?username=username&type=type&o=12
。然后,我在profile.php中使用php获取
if(isset($\u get['username']){}
if(isset($\u get['type']){}
if(isset($\u get['o']){}
来获取变量。@Bruce是的,我可以看到这些指令的作用-它们没有问题。关于您现有的重写,我只是说这两个
RewriteCond
指令是多余的,应该删除(它们执行两个不必要的文件系统检查)。为了“在特定URL的末尾强制执行
/
”,您需要一个重定向,正如我上面提到的。这对你有用吗?重定向必须在您现有的重写之前进行。我拼凑了一个自己的解决方案,并使用提供的两个答案添加了它。:)我明白你的意思,是的,这只是一种习惯,以防止冲突的情况下,在某些点目录有相同的名称作为文件-尽管这可能是不太可能的。