当“index.html”被剥离时,如何删除“/folder/index.html”的尾部斜杠?

uno*_*nor 5 .htaccess mod-rewrite url-rewriting trailing-slash

我有一个具有以下文件/文件夹结构的静态站点:

  • 索引.html
  • /foobar/
    • 索引.html
    • 鲍勃.html
    • 爱丽丝.html

我想实现以下目标:

  • 删除所有.html扩展。? 作品
  • 删除index.html(分别index)。? 作品
  • 我希望文件结束时不带斜杠。? 作品
    • 如果有人添加了尾部斜杠,则重定向到没有尾部斜杠的 URL。? 不起作用
  • 我希望“文件夹”(实际上是index.html文件夹内的文件)结束时不带斜杠。? 不起作用
    • 如果有人添加了尾部斜杠,则重定向到没有尾部斜杠的 URL。? 不起作用

因此,以下 URL 应该有效:

  • example.com/(实际上是:/index.html
  • example.com/foobar(实际上是:/foobar/index.html
  • example.com/foobar/bob(实际上是:/foobar/bob.html
  • example.com/foobar/alice(实际上是:/foobar/alice.html

以下请求应重定向 (301):

  • example.com/foobar/重定向到:example.com/foobar
  • example.com/foobar/bob/重定向到:example.com/foobar/bob
  • example.com/foobar/alice/重定向到:example.com/foobar/alice

我看到这会在文件/foobar.html存在时产生问题:当有人访问 时/foobar,不清楚是请求目录还是文件。但是,我会确保这永远不会发生。


目前,我有这个.htaccess

# Turn MultiViews off. (MultiViews on causes /abc to go to /abc.ext.) 
Options +FollowSymLinks -MultiViews

# It stops DirectorySlash from being processed if mod_rewrite isn't. 
<IfModule mod_rewrite.c>

    # Disable mod_dir adding missing trailing slashes to directory requests.
    DirectorySlash Off

    RewriteEngine On

    # If it's a request to index(.html) 
    RewriteCond %{THE_REQUEST} \ /(.+/)?index(\.html)?(\?.*)?\  [NC]
    # Remove it. 
    RewriteRule ^(.+/)?index(\.html)?$ /%1 [R=301,L]

    # Add missing trailing slashes to directories if a matching .html does not exist. 
    # If it's a request to a directory. 
    RewriteCond %{SCRIPT_FILENAME}/ -d
    # And a HTML file does not (!) exist.
    RewriteCond %{SCRIPT_FILENAME}.html !-f
    # And there is not trailing slash redirect to add it. 
    RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L]

    # Remove HTML extensions. 
    # If it's a request from a browser, not an internal request by Apache/mod_rewrite. 
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    # And the request has a HTML extension. Redirect to remove it. 
    RewriteRule ^(.+)\.html$ /$1 [R=301,L]

    # If the request exists with a .html extension. 
    RewriteCond %{SCRIPT_FILENAME}.html -f
    # And there is no trailing slash, rewrite to add the .html extension. 
    RewriteRule [^/]$ %{REQUEST_URI}.html [QSA,L]

</IfModule>
Run Code Online (Sandbox Code Playgroud)

我需要更改/删除/添加.htaccess什么?我不太明白。我试图删除注释为“如果匹配的 .html 不存在,则向目录添加缺少的尾随斜杠”的块,但这没有帮助。

Jon*_*Lin 4

在您的规则正上方# Add missing trailing slashes to directories if a matching .html does not exist.,尝试添加此规则,当存在 html 文件且请求不是目录并且有尾部斜杠时进行重定向:

# if request has a trailing slash
RewriteCond %{REQUEST_URI} ^/(.*)/$
# but it isn't a directory
RewriteCond %{DOCUMENT_ROOT}/%1 !-d
# and if the trailing slash is removed and a .html appended to the end, it IS a file
RewriteCond %{DOCUMENT_ROOT}/%1.html -f
# redirect without trailing slash
RewriteRule ^ /%1 [L,R=301]
Run Code Online (Sandbox Code Playgroud)

这不应该与它后面的重定向规则冲突,因为它的条件检查完全相反。


编辑:

要处理index.html,您需要更改现有的规则,即附加尾部斜杠:

# Add missing trailing slashes to directories if a matching .html does not exist. 
# If it's a request to a directory. 
RewriteCond %{SCRIPT_FILENAME}/ -d
# And a HTML file does not (!) exist.
RewriteCond %{SCRIPT_FILENAME}.html !-f
# And there is not trailing slash redirect to add it. 
RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L]
Run Code Online (Sandbox Code Playgroud)

到:

# Add missing trailing slashes to directories if a matching .html does not exist. 
# If it's a request to a directory. 
RewriteCond %{REQUEST_FILENAME}/ -d
# And a HTML file does not (!) exist.
RewriteCond %{REQUEST_FILENAME}/index.html !-f
# And there is not trailing slash redirect to add it. 
RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L]    
Run Code Online (Sandbox Code Playgroud)

这会在添加尾部斜杠之前检查目录中是否缺少index.html该文件。您必须这样做的原因是因为缺少尾部斜杠时的信息泄露安全问题实际上会暴露您的所有目录内容(如果您没有尾部斜杠)。现在,添加这些规则以在存在 时删除尾随斜杠:index.html

RewriteCond %{REQUEST_FILENAME} -d
# And a HTML file exists.
RewriteCond %{REQUEST_FILENAME}/index.html -f
# And there is a trailing slash redirect to remove it. 
RewriteRule ^(.*?)/$ /$1 [R=301,L]    
Run Code Online (Sandbox Code Playgroud)

index.html现在,在没有尾部斜杠时立即添加这些规则以显式显示(注意R=301规则标志中的 no):

RewriteCond %{REQUEST_FILENAME} -d
# And a HTML file exists.
RewriteCond %{REQUEST_FILENAME}/index.html -f
# And there is no trailing slash show the index.html. 
RewriteRule [^/]$ %{REQUEST_URI}/index.html [L]    
Run Code Online (Sandbox Code Playgroud)