我有一個帶有 index.php 的 MVC 應用程式,位于 /public 子檔案夾中。目前,我將 Apache 指向 /public 檔案夾并在其中使用 .htaccess 將 MVC 請求重寫為 index.php。
當前的 Apache 配置:
<VirtualHost>
DocumentRoot /var/www/html/public
</VirtualHost>
/public 中的當前 .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
目標 Apache 配置:
<VirtualHost>
DocumentRoot /var/www/html
</VirtualHost>
目標 .htaccess,但我無法同時正確重寫 MVC 和資產 URL:
DirectoryIndex index.php
RewriteEngine On
RewriteBase /public
# If it's a file/directory/symlink, serve it.
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^.*$ - [NC,L]
# Otherwise let's go MVC
RewriteRule ^.*$ index.php [NC,L]
示例網址:
domain.com/login (MVC URL, rewritten to public/index.php)
domain.com/assets/styles.css (non-MVC URL, rewritten to public/assets folder)
uj5u.com熱心網友回復:
除非您設定本地開發環境來模擬更嚴格的實時服務器環境,否則......
不知道為什么要這樣做,因為您當前的配置(設定
DocumentRoot為/public)似乎是最理想的(也是最簡單的)設定。當您無法更改.
DocumentRoot_ 這最終需要更多的作業并暴露子目錄,現在必須阻止/重定向以防止直接訪問。/publicDocumentRoot/public
無論如何,移動到/public公共 HTML 空間中的子目錄...
將 設定為DocumentRoot后,/var/www/html有兩種方法可以完成此操作,使用 1 個或 2 個.htaccess檔案。(雖然,這也引發了另一個問題......當你可以訪問服務器配置時,你為什么要使用.htaccess?雖然這可能有完全正當的理由。)
方法#1 - 兩個.htaccess檔案
.htaccess可以說使用兩個檔案更容易做到這一點。一個在檔案根目錄中重寫所有對/public子目錄的請求,另一個在/public子目錄中重寫對您的 MVC 應用程式的請求,與您已經在做的方式大致相同。該/public/.htaccess檔案的存在還可以防止重寫回圈。
例如:
# (1) /.htaccess
RewriteEngine On
# (OPTIONAL) If you need to allow access to files/directories/symlinks
# outside of the "public" directory
#RewriteCond %{REQUEST_FILENAME} -f [OR]
#RewriteCond %{REQUEST_FILENAME} -d [OR]
#RewriteCond %{REQUEST_FILENAME} -l
#RewriteRule ^ - [L]
# Rewrite all requests to the "/public" subdirectory
RewriteRule (.*) public/$1 [L]
# (2) /public/.htaccess
RewriteEngine On
# If "public" directory is requested directly then redirect to remove it
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /$1 [R=301,L]
# Stop early if already rewritten to MVC
RewriteRule ^index\.php$ - [L]
# Rewrite to MVC app, otherwise serve assets
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule (.*) index.php?$1 [QSA,L]
方法#2 -.htaccess檔案根目錄中的一個檔案
或者,您在檔案根目錄中只有一個.htaccess檔案。
例如:
# /.htaccess (only)
RewriteEngine On
# If "public" directory is requested directly then redirect to remove it
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^public(?:/(.*))?$ /$1 [R=301,L]
# Stop early if already rewritten to "public" directory
RewriteRule ^public/ - [L]
# If it's a file/directory/symlink, serve it.
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
# Rewrite to assets in "public" directory if they exist
RewriteCond %{REQUEST_URI} \.\w{2,4}$
RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -f
RewriteRule !^public/ public%{REQUEST_URI} [L]
# Otherwise rewrite request to the MVC app in "public" directory
RewriteRule (.*) public/index.php?$1 [QSA,L]
我假設您所有的“資產”的檔案擴展名都在 2 到 4 個字符之間。對上述內容的優化是,如果您的所有“資產”都被參考,/assets/...那么您可以簡單地將所有這些請求重寫為/public/assets/...- 無需檔案系統檢查。例如:
# Rewrite to assets in "public" directory (unconditionally)
RewriteRule ^assets/ public%{REQUEST_URI} [L]
Although this would mean you cannot have routes in the MVC app that start /assets/. But you probably shouldn't anyway.
Aside: If you aren't serving directories directly (it's unusual to do so these days) then you don't need to check whether the request maps to a directory in the rewrite rules. Just allow it to pass to your MVC app and trigger a 404 (rather than a 403) - which could be preferable.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/426653.html
