htaccess规范网址子目录

时间:2017-01-21 00:16:00

标签: apache .htaccess mod-rewrite

我遇到与htaccess - canonical URL when redirecting to subdirectory相同的问题,但是那里的解决方案似乎在htaccess文件中使用了一个我不能做的硬编码主机名。

以下是我的根目录中的htaccess文件,可以将所有请求重定向到/public目录,但node_modules除外:

<IfModule mod_rewrite.c>
   RewriteEngine on
   # Allow node_modules
   RewriteRule ^node_modules($|/) - [L]
   # Rewrite everything to public
   RewriteRule ^(.*)$ public/$1 [L,QSA]
</IfModule>

但是我意识到可以通过两个不同的URL访问这些页面,例如:

  • https://localhost/application1/foo/books.php
  • https://localhost/application1/public/foo/books.php

如何阻止第二个(理想情况下)或将其重定向到第一个?

我尝试了%{THE_REQUEST}的各种RewriteCond语句,但结果却是无限循环。如上所述,由于应用程序在不同的环境中运行,因此需要与主机名无关。

更新

我在我的.htaccess中尝试了以下@SuperDuperApps的答案,这似乎没什么区别:

RewriteEngine on
RewriteCond $1 !^node_modules($|/)
RewriteCond $1 !^public($|/)
RewriteRule ^(.*)$ public/$1 [L,QSA]
RewriteRule ^public/ - [L,R=404]

在我的开发服务器中启用RewriteLogLevel 3后,当我访问网址中包含/public的文件时,会显示以下内容:

192.168.33.1 - - [27/Jan/2017:22:52:45 --0500] [localhost/sid#7f4a0d1d2cf0][rid#7f4a0d6a5d58/initial] (1) [perdir /var/www/html/application1/public/] pass through /var/www/html/application1/public/common/assets/js/nav.min.js

这是我访问URL中没有/public的同一文件时所需的行为:

192.168.33.1 - - [27/Jan/2017:22:48:45 --0500] [localhost/sid#7f4a0d1d2cf0][rid#7f4a0d684738/initial] (3) [perdir /var/www/html/application1/] add path info postfix: /var/www/html/application1/common -> /var/www/html/application1/common/assets/js/nav.min.js
192.168.33.1 - - [27/Jan/2017:22:48:45 --0500] [localhost/sid#7f4a0d1d2cf0][rid#7f4a0d684738/initial] (3) [perdir /var/www/html/application1/] strip per-dir prefix: /var/www/html/application1/common/assets/js/nav.min.js -> common/assets/js/nav.min.js
192.168.33.1 - - [27/Jan/2017:22:48:45 --0500] [localhost/sid#7f4a0d1d2cf0][rid#7f4a0d684738/initial] (3) [perdir /var/www/html/application1/] applying pattern '^(.*)$' to uri 'common/assets/js/nav.min.js'
192.168.33.1 - - [27/Jan/2017:22:48:45 --0500] [localhost/sid#7f4a0d1d2cf0][rid#7f4a0d684738/initial] (2) [perdir /var/www/html/application1/] rewrite 'common/assets/js/nav.min.js' -> 'public/common/assets/js/nav.min.js'
192.168.33.1 - - [27/Jan/2017:22:48:45 --0500] [localhost/sid#7f4a0d1d2cf0][rid#7f4a0d684738/initial] (3) [perdir /var/www/html/application1/] add per-dir prefix: public/common/assets/js/nav.min.js -> /var/www/html/application1/public/common/assets/js/nav.min.js
192.168.33.1 - - [27/Jan/2017:22:48:45 --0500] [localhost/sid#7f4a0d1d2cf0][rid#7f4a0d684738/initial] (2) [perdir /var/www/html/application1/] strip document_root prefix: /var/www/html/application1/public/common/assets/js/nav.min.js -> /application1/public/common/assets/js/nav.min.js
192.168.33.1 - - [27/Jan/2017:22:48:45 --0500] [localhost/sid#7f4a0d1d2cf0][rid#7f4a0d684738/initial] (1) [perdir /var/www/html/application1/] internal redirect with /application1/public/common/assets/js/nav.min.js [INTERNAL REDIRECT]
192.168.33.1 - - [27/Jan/2017:22:48:45 --0500] [localhost/sid#7f4a0d1d2cf0][rid#7f4a0d676688/initial/redir#1] (1) [perdir /var/www/html/application1/public/] pass through /var/www/html/application1/public/common/assets/js/nav.min.js

2 个答案:

答案 0 :(得分:0)

这应该这样做:

RewriteEngine on
# Allow node_modules
RewriteCond $1 !^node_modules($|/)
# Rewrite everything to public except public
RewriteCond $1 !^public($|/)
RewriteRule ^(.*)$ public/$1 [L,QSA]
# 404 diret access to public
RewriteRule ^public/ - [L,R=404]

答案 1 :(得分:0)

使用两个单独的文件。

htaccess的:

<IfModule mod_rewrite.c>
   RewriteEngine on
   # Allow node_modules
   RewriteRule ^node_modules($|/) - [L]
   # Rewrite everything to public
   RewriteRule ^(.*)$ public/$1 [L,QSA]
</IfModule>
公共场所内的

.htaccess:

<IfModule mod_rewrite.c>
    RewriteEngine on

    # pass-through if another rewrite rule has been applied already
    RewriteCond %{ENV:REDIRECT_STATUS} 200
    RewriteRule .* - [S=1] # Skip the next rule
    RewriteRule ^ - [L,R=404]

    # ...additional rules here as needed
</IfModule>
如果没有其他规则,则可以在第二个文件中使用

[L]代替[S=1]

This question向我提出了“传递重定向”的想法。

还要感谢@SuperDuperApps用于RewriteLogLevel的调试提示,以及带有[END]标志的原始答案,如果我有Apache 2.4,可能会有效。