htaccess 重定向到 public 目录中可用的文件

htaccess redirecting to files available in the public directory

[背景]
这是我的应用程序的结构:

app/
    controllers/
        ...
    modules/
        ...
    views/
        ...
public/
    css/
        main.css
    images/
        ...
    js/
        ...
    index.php 
.htaccess

出于各种原因(安全、组织等),public 应用程序(网站)由 public/index.php 加载和显示 在我服务器的“根目录”,我有以下内容 .htaccess 文件:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /BU/cs-602/developer-story/
    RewriteRule ^(\/||index\.*)$ public/index.php [L,QSA]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-l
    RedirectMatch ^(/BU/cs-602/developer-story.)([\w\d\s\/\-\:\_%\ ]*\.css)$ public/ [L]
    RewriteRule ^([\w\d\-\_\/\ ]*)$ public/index.php?p= [L,QSA]
</IfModule>

这些规则应该重写/重定向来自服务器“root”的所有请求到public/index.php 因为我在我的开发服务器上进行本地开发,这个项目实际上并不在我的服务器的根目录中,而是位于 /BU/cs-602/developer-story/ 这就是我添加 RewriteBase 规则的原因。

如果我删除 RedirectMatch 规则,从 MVC 的角度来看,一切都有效:

URL 像 http://localhost/BU/cs-602/developer-storyhttp://localhost/BU/cs-602/developer-story/ 变成了 http://localhost/BU/cs-602/developer-story/public/index.php 和 URL 像 http://localhost/BU/cs-602/developer-story/user/id 变成了 http://localhost/BU/cs-602/developer-story/public/index.php?p=user/id.

现场直播htaccess test.

[问题]
如何修复 .htaccess 文件或 RedirectMatch 规则以将请求重定向到 CSSJS 文件等资源?当前规则适用于 tester 但不适用于我的服务器,除非我删除 RedirectMatch 规则。

我希望像 http://localhost/BU/cs-602/developer-story/css/main.css 这样的 URL 在我的 HTML 中变成 http://localhost/BU/cs-602/developer-story/public/css/main.css 我会做类似的事情:

<img src="images/logo.png">

服务器实际加载:

<img src="public/images/logo.png">

这样我就不必为所有资源添加前缀 public/

[披露]
这个问题是为了帮助我大学的期末项目,但这种类型的问题是允许的,并且不违反学术政策。使用 htaccessMVC 制作项目不是必需的,只是我正在做的挑战自己的事情。

更新:
这是我原来的 RedirectMacth 规则。任何不是 PHP 或 HTML 文件的内容都会被重定向:

RedirectMatch ([\w\d\s\/\-\:\_%\ ]*\.(?!php|htm|html))  [L]

我在查看服务器上的错误日志后找到了解决方案。我的各种尝试导致重定向循环。这是我的工作 .htaccess 文件,以防它帮助任何人尝试做类似的事情。

关键是在必要时短路 .htaccess 文件,这样它就不会无限地重写您的 URL。我添加了内嵌注释来解释这个过程:

# Redirect all requests to the public directory.
<IfModule mod_rewrite.c>
    RewriteEngine On
    # Only needing for local develoment in my case.
    RewriteBase /BU/cs-602/developer-story/
    # If nothing or an index page is requested go to `public/index.php` and stop processing.
    RewriteRule ^(\/||.*index\..*)$ public/index.php [L,QSA]
    # If the URL already contains the `public/` directory go to URL and stop processing.
    RewriteRule ^(.*public\/.*)$  [L,QSA]
    # If it appears this URL is for a resource (JS, CSS, etc.) prefix with `public/`.
    RewriteCond %{REQUEST_URI} ^([\w\d\s\-\_\/\%]*)\.(?!php|htm|html).*$
    # Go to the modified URL if the last rule triggered and stop processing.
    RewriteRule ^(.*)$ public/ [L,QSA]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-l
    # Rewrite all remaing URLs to our apps MVC structure.
    RewriteRule ^([\w\d\s\-\_\/\%]*)$ public/index.php?p= [L,QSA]
</IfModule>