【问题标题】:htaccess canonical URL subdirectoryhtaccess 规范 URL 子目录
【发布时间】:2017-01-28 13:33:00
【问题描述】:

我和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 后,当我访问URL 中带有/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

【问题讨论】:

    标签: apache .htaccess mod-rewrite


    【解决方案1】:

    应该这样做:

    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]
    

    【讨论】:

    • 似乎没有任何作用:/
    • 请更具体一些,您尝试了什么,发生了什么?
    • 我尝试将我的 htaccess 文件中的块更改为您的答案中的块,它继续将所有内容重定向到 public,但并未阻止访问 public 本身。我必须将 END 更改为 L,因为我使用的是 Apache 2.2,但我认为这不会有什么不同。
    • 块在你的 .htaccess 文件中?您有权访问服务器配置吗?如果是这样,请将 3 级重写日志添加到 VirtualHost 并在您访问 /public/ 时发布跟踪。你可以用this来做到这一点。
    【解决方案2】:

    可以处理两个单独的文件。

    .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 里面 public:

    <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 可能会起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      • 1970-01-01
      • 2016-05-05
      • 2010-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多