本教程旨在解決 laravel 項目部署到共享主機(如 000webhost)后,內部鏈接出現 404 錯誤的問題。核心解決方案是通過在網站根目錄配置 .htaccess 文件,確保服務器正確重寫 URL 并將所有請求導向 Laravel 的 index.php 前端控制器,從而恢復路由功能。
理解 Laravel 路由與共享主機環境的挑戰
Laravel 框架采用“前端控制器”模式,這意味著所有 http 請求都應通過位于項目 public 目錄下的 index.php 文件進行處理。index.php 負責加載框架核心,解析請求的 URL,并將其路由到相應的控制器或閉包函數。在本地開發環境中,通常由 PHP 內置服務器、nginx 或 apache 配置來確保所有請求都正確地重定向到 index.php。
然而,當 Laravel 項目部署到某些共享主機環境時,服務器的默認配置可能無法識別這種重寫規則,導致除了根 URL (/) 之外的所有內部鏈接都返回 404 錯誤。這是因為服務器在文件系統中找不到與請求 URL 直接對應的物理文件或目錄,而沒有將請求轉發給 index.php 進行動態處理。
解決方案:配置 .htAccess 文件
解決此問題的關鍵在于為 Apache 服務器配置正確的 URL 重寫規則。這通常通過在網站的文檔根目錄(在 000webhost 這樣的主機上通常是 public_html 目錄)中創建一個或修改現有的 .htaccess 文件來實現。此文件將指示 Apache 如何處理傳入的請求,確保它們被 Laravel 的 index.php 文件捕獲。
以下是適用于 Laravel 項目的 .htaccess 文件內容:
<IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews </IfModule> RewriteEngine On # 移除尾部斜杠,如果不是目錄的話 RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1 [L,R=301] # 處理前端控制器:將所有非文件/非目錄請求重寫到 index.php RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] # 處理授權頭部 RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] </IfModule>
.htaccess 文件內容解析:
-
: 這是一個條件塊,確保只有在 Apache 服務器啟用了 mod_rewrite 模塊時,其中的規則才會被應用。這是 URL 重寫功能的基礎。 -
Options -MultiViews : MultiViews 是 Apache 的一個功能,它允許服務器嘗試自動查找與請求文件名匹配的文件(例如,請求 example 但存在 example.php 或 example.html)。禁用此選項可以防止與 Laravel 的路由系統發生沖突,確保請求完全由 .htaccess 規則控制。 - RewriteEngine On: 顯式開啟 Apache 的 URL 重寫引擎。
- RewriteCond %{REQUEST_FILENAME} !-d 和 *`RewriteRule ^(.)/$ /$1 [L,R=301]`**:
- RewriteCond %{REQUEST_FILENAME} !-d: 這是一個條件,表示只有當請求的 URI 不是一個實際存在的目錄時,才應用后續的規則。
- RewriteRule ^(.*)/$ /$1 [L,R=301]: 這條規則會移除 URL 末尾多余的斜杠(例如 example.com/about/ 會被重定向到 example.com/about)。[L] 表示這是最后一條規則,[R=301] 表示執行一個永久重定向。
- RewriteCond %{REQUEST_FILENAME} !-d 和 RewriteCond %{REQUEST_FILENAME} !-f 和 RewriteRule ^ index.php [L]:
- RewriteCond %{REQUEST_FILENAME} !-d: 條件,如果請求的 URI 不是一個實際存在的目錄。
- RewriteCond %{REQUEST_FILENAME} !-f: 條件,如果請求的 URI 不是一個實際存在的文件。
- RewriteRule ^ index.php [L]: 這是 Laravel 路由的核心。如果上述兩個條件都滿足(即請求的 URI 既不是文件也不是目錄),則將所有請求重寫到 index.php。^ 匹配任何請求,[L] 表示這是最后一條重寫規則。
- RewriteCond %{HTTP:Authorization} . 和 *`RewriteRule . – [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]`**:
- 這兩行規則確保 HTTP 請求中的 Authorization 頭部信息能夠被正確地傳遞給 PHP 應用程序。這對于處理 API 請求中的認證令牌(如 Bearer Token)至關重要。
實施步驟
- 準備 Laravel 項目文件: 通常,為了在共享主機上部署 Laravel,你需要將 Laravel 項目 public 目錄下的所有內容(包括 index.php、.htaccess 文件、css/JS/圖片等靜態資源)直接上傳到主機的文檔根目錄(例如 public_html)。項目的其余部分(app、bootstrap、vendor 等)應該上傳到 public_html 的上一級目錄或同級目錄,以保證其安全性和私密性。
- 創建或修改 .htaccess 文件:
- 在你的本地 Laravel 項目的 public 目錄下,通常已經有一個 .htaccess 文件。確認其內容與上述示例一致。
- 如果你的 public_html 目錄中沒有 .htaccess 文件,或者其內容不正確,請創建一個新文件并粘貼上述代碼。
- 如果已經存在 .htaccess 文件,請備份原有內容,然后替換為上述代碼。
- 上傳文件: 使用 FTP 客戶端或主機提供的文件管理器,將修改后的 .htaccess 文件上傳到你的網站根目錄(例如 public_html)。
- 清除 Laravel 緩存(可選但推薦): 部署后,清除 Laravel 應用程序的配置、路由和視圖緩存通常是一個好習慣,以確保所有更改生效。如果你的主機支持 ssh 訪問,可以運行:
php artisan config:clear php artisan route:clear php artisan view:clear
如果不支持 SSH,可能需要手動刪除 bootstrap/cache 目錄下的緩存文件,或者在 public/index.php 中臨時添加 Artisan::call(‘cache:clear’); 等代碼(完成后務必刪除)。
注意事項
- mod_rewrite 模塊: 確保你的共享主機已啟用 Apache 的 mod_rewrite 模塊。大多數現代主機默認都會啟用,但如果問題依然存在,請聯系你的主機提供商確認。
- 文件權限: 確保 .htaccess 文件的權限設置正確,通常是 644 或 664,以允許服務器讀取。
- 根目錄結構: 上述解決方案假設你已將 Laravel 項目的 public 目錄內容直接放在了網站的文檔根目錄(如 public_html)。如果你的部署結構不同,例如 public_html/laravel/public,那么 .htaccess 文件可能需要放置在 public_html 下,并且可能需要調整 Laravel 的 index.php 來正確加載框架核心。
- 其他服務器類型: 如果你的主機使用的是 Nginx 而非 Apache,那么 .htaccess 文件將不起作用。Nginx 需要在其配置文件中進行類似的 URL 重寫配置。
總結
通過在共享主機的文檔根目錄中正確配置 .htaccess 文件,可以有效解決 Laravel 項目部署后內部鏈接 404 的問題。這個 .htaccess 文件確保了所有非文件、非目錄的請求都被重定向到 index.php,從而讓 Laravel 的路由系統能夠正常工作。理解其背后的原理和每個規則的作用,有助于在遇到類似問題時進行快速排查和解決。