【问题标题】:How do I get mod_rewrite to both remove file extensions and redirect certain URLs?如何让 mod_rewrite 删除文件扩展名和重定向某些 URL?
【发布时间】:2012-05-23 19:09:44
【问题描述】:

所以我试图让 mod_rewrite 做一些不同的事情,但我并不完全同意它。我愿意:

  1. 从 URL 中删除文件扩展名(在本例中为 .shtml)
  2. 像这样重写某些 URL:

    /dashboard       -> /ui/dashboard/index.shtml
    /dashboard/      -> /ui/dashboard/index.shtml
    /dashboard/list  -> /ui/dashboard/list.shtml
    /dashboard/list/ -> /ui/dashboard/list.shtml
    /workspace       -> /ui/workspace/index.shtml
    /workspace/      -> /ui/workspace/index.shtml
    /account/manage  -> /ui/account/manage.shtml
    /account/manage/ -> /ui/account/manage.shtml
    
  3. 添加或删除尾部斜杠(我不在乎,只要一致即可)

我目前拥有的东西让我完成了大约 90% 的工作。在我的 .htaccess 文件中,我有以下内容:

DirectoryIndex index.shtml index.html index.htm

<IfModule mod_rewrite.c>

  Options +FollowSymlinks
  RewriteEngine On
  RewriteBase /

  # Get rid of the /ui/ in the URLs
  RewriteRule ^(account|workspace|dashboard)([a-zA-Z0-9\-_\.\/]+)?$ /ui/$1$2 [NC,L]

  # Add the trailing slash
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/|#(.*))$
  RewriteRule ^(.*)$ $1/ [R=301,L]

  # Remove the shtml extension
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME}.shtml -f
  RewriteRule ^([^\.]+)/$ $1\.shtml

</IfModule>

现在我遇到的问题是双重的:

首先,如果我尝试访问上面第 2 步中列出的目录中列出的索引页面之一,只要我使用尾部斜杠就可以了,但如果我省略尾部斜杠,则 URL 会重写不正确(但是页面仍然加载)。例如

/dashboard/   remains /dashboard/ in the address bar.
/dashboard    rewrites to /ui/dashboard/ in the address bar.

如何让这些index.shtml页面保持地址栏一致?

其次,当我尝试访问其中一个重写目录中的目录索引以外的页面时,并且我包含一个尾部斜杠时,它会给我一个 404 错误。例如:

/dashboard/list/

抛出 404 错误:

The requested URL /ui/dashboard/list.shtml/ was not found on this server.

非常感谢您提供的任何帮助以使其正常工作。

【问题讨论】:

  • RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/|#(.*))$ 与 .shtml 不匹配是导致错误号 2; %{REQUEST_URI} 可能不是您需要匹配的,请尝试匹配 %{SCRIPT_NAME}

标签: apache .htaccess mod-rewrite


【解决方案1】:

所以我想出了一种适合我需要的方法。这是我想出的 .htaccess,内联注释:

# Match URLs that aren't a file
RewriteCond %{REQUEST_FILENAME} !-f

# nor a directory
RewriteCond %{REQUEST_FILENAME} !-d

# if it's the index page of the directory we want, show that and go no further
RewriteRule ^(account|workspace|dashboard)/?$ /ui/$1/index.shtml [L]

# If we've gotten here, we're dealing with something other than the directory index.
# Let's remove the trailing slash internally
# This takes care of my second issue in my original question
RewriteRule ^(.*)/$ $1 [L]

# Do the rewrite for the the non-directory-index files. 
RewriteRule ^(account|workspace|dashboard)([a-zA-Z0-9\-_\.\/]+)?$ /ui/$1$2 [L]

不确定这是否是最有效的方法,但它可以满足我的需求。我想我会在这里分享它以防它帮助其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 2017-05-05
    • 2017-04-30
    相关资源
    最近更新 更多