htaccess - 在动态 URL 的末尾强制添加斜线

htaccess - Force a slash to the end of a dynamic URL

我在 /slug 子目录中有一个 index.php 文件,我想根据文件路径加载动态内容。不管 url 是什么,内容都应该引用 index.php.

在我下面的代码中,url 末尾没有添加斜线。例如,example.com/slug/33 在地址栏中应该显示为 example.com/slug/33/.

我在 /slug 中有以下 .htaccess:

Options -Indexes

# Turn mod_rewrite on
RewriteEngine On
RewriteBase /

# Dynamic url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /slug/index.php/?path= [NC,L,QSA]

我尝试在 index.php?path=$ 之间添加一个 /,但我没有得到想要的结果。这可能吗?

RewriteRule ^(.*)$ /slug/index.php/?path= [NC,L,QSA]

在此处更改 substitution 字符串会更改内部重写的目标 - 它不会更改可见的 URL。通过在 index.php 之后添加斜杠,您(不必要地)将额外的路径名信息 (path-info) 添加到您的应用程序收到的结果 URL 中。

要更改可见的 URL(附加斜杠),您需要实施外部重定向。但是,要确认...您必须已经在内部链接中链接到正确的规范 URL(即带有斜线)。仅当您更改了 URL 并且搜索引擎或第 3 方仍在使用旧的非规范 URL(没有尾部斜线)。

由于 .htaccess 文件位于 /slug 子目录中,而您正在该子目录中重写 index.php,因此您不需要为重写的 URL 添加前缀/slug/。默认情况下,相对 URL 路径是相对于包含 .htaccess 文件的目录的。但是,您还必须删除 RewriteBase 指令(或将其“正确”设置为 RewriteBase /slug)。

要重定向以附加尾部斜线,您可以在当前重写之前添加以下内容:

# Append trailing slash if omitted
RewriteRule ^(.*(?:^|/)[^/.]+)$ /slug// [R=301,L]

这需要 替换 字符串上的 /slug/ 前缀(除非设置了 RewriteBase /slug),否则外部重定向将尝试重定向到文件-路径,这将“中断”。

RewriteRule 模式 ^(.*(?:^|/)[^/.]+)$ 捕获 URL-路径,这些路径尚未以斜杠结尾且不包含点最后一个路径段。这是为了避免匹配已经包含(看起来像)文件扩展名的 URLs,即。您的静态资源(图片、CSS、JS 等)。这应该避免需要文件系统检查(这是相对昂贵的)——检查请求是否已经映射到文件。虽然,如果您没有在 URL 中引用任何带有 /slug/ 前缀的静态资源,那么这可以简化。

注意:您应该首先使用 302(临时)重定向进行测试,以避免潜在的缓存问题。

上下文中(使用 RewriteBase):

Options -Indexes

# Turn mod_rewrite on
RewriteEngine On
RewriteBase /slug

# Append trailing slash if omitted
RewriteRule ^(.*(?:^|/)[^/.]+)$ / [R=301,L]

# Dynamic url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+) index.php?path= [QSA,L]

使用 RewriteBase 可以避免在其他指令中指定 /slug/

在正则表达式 ^(.*)$ 中,字符串开头 (^) 和字符串结尾 ($) 锚点是多余的。您也可以将其更改为使用 + 量词,因为无论如何您都不想匹配基本目录(保存两个额外的文件系统检查)。 NC 标志在这里也是多余的。