为何URL仍显示/public?Laravel路由重写规则问题求助
解决cPanel环境下Laravel项目URL自动带/public的问题
我来帮你解决这个问题——我之前在cPanel上部署Laravel的时候也遇到过一模一样的情况!
先说说你现有规则只适配首页的原因
你当前的重写规则核心问题在于:
- 最后一条规则
RewriteRule ^(/)?$ subfolder/index.php [L]只匹配空路径(首页),只有访问www.example.com时才会触发指向subfolder/index.php; - 其他请求的
RewriteRule ^(.*)$ /subfolder/$1只是把路径转到了subfolder目录,但没有指定要通过subfolder/index.php这个Laravel入口文件来处理,服务器找不到对应的静态文件,就会自动暴露public路径; - 条件里的
RewriteCond %{REQUEST_URI} !^/subfolder/还会阻止对已包含subfolder路径的请求进行处理,进一步限制了规则的作用范围。
适配所有页面的正确重写规则
你需要在public_html目录下创建(或修改).htaccess文件,把所有请求都转发到Laravel的public/index.php,同时隐藏URL里的public。以下是完整配置:
<IfModule mod_rewrite.c> RewriteEngine On # 可选:强制非www域名跳转到www(根据你的需求调整) RewriteCond %{HTTP_HOST} ^example.com$ RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L] # 核心规则:将所有非静态资源请求转发到public/index.php RewriteCond %{REQUEST_URI} !^/public/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ public/index.php/$1 [L] # 单独处理首页请求,确保直接指向入口文件 RewriteCond %{REQUEST_URI} ^/$ RewriteRule ^(.*)$ public/index.php [L] </IfModule>
规则说明
- 开启重写引擎:
RewriteEngine On是所有重写规则的基础; - 域名统一(可选):把非www域名跳转到www,避免重复内容,同时确保路由一致性;
- 核心转发规则:
RewriteCond %{REQUEST_URI} !^/public/:排除已包含public的请求,防止循环重写;RewriteCond %{REQUEST_FILENAME} !-f和RewriteCond %{REQUEST_FILENAME} !-d:判断请求的文件或目录是否存在,如果是静态资源(比如图片、CSS)就直接返回,否则交给Laravel处理;RewriteRule ^(.*)$ public/index.php/$1 [L]:把所有动态请求转发到public/index.php,并保留原请求路径;
- 首页处理:单独匹配空路径,确保首页直接指向入口文件。
额外注意事项
请确保Laravel项目public目录下的.htaccess保持默认的Laravel配置(不要修改),它负责处理Laravel内部的路由逻辑:
<IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews -Indexes </IfModule> RewriteEngine On # Handle Authorization Header RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] # Redirect Trailing Slashes If Not A Folder... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [L,R=301] # Send Requests To Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] </IfModule>
配置完成后,不管访问首页还是其他路由(比如www.example.com/about),都会加载public/index.php,URL里不会显示public,所有Laravel路由都能正常工作。
内容的提问来源于stack exchange,提问作者ajw4sk
相关产品推荐
相关产品推荐

