Laravel 9部署于CPanel,符号链接文件夹无法通过URL访问
Laravel CPanel下符号链接访问404问题解决指南
核心排查方向与解决方案
1. 确认符号链接位置是否匹配URL路径
你访问的是domain.com/storage/xxx,但当前符号链接建在api.domain.com的目录下(/home/account/api.domain.com/storage)。如果domain.com的根目录不是api.domain.com的目录(比如domain.com对应/home/account/public_html),那符号链接完全建错了位置。
修正操作:删除旧符号链接,在domain.com的根目录下重新创建:
symlink('/home/account/laravel-project/storage/app/public','/home/account/public_html/storage');
执行后刷新文件管理器确认链接生效。
2. 修复权限与所有权问题
CPanel共享主机对权限要求严格,即使符号链接本身正确,目标目录/文件的权限或所有权不对也会导致404:
- 目标目录权限:
/home/account/laravel-project/storage/app/public及其所有子目录设置为755 - 文件权限:上传的图片文件设置为
644 - 所有权:确保目标目录和文件的所有者与网站运行用户一致(通常是你的CPanel账户名),执行命令:
chown -R account:account /home/account/laravel-project/storage/app/public
3. 调整.htaccess规则顺序
当前.htaccess中Options +FollowSymLinks的位置可能导致规则冲突,修改为以下结构:
<IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews -Indexes +FollowSymLinks </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 RewriteCond %{REQUEST_FILENAME} !-l RewriteRule ^ index.php [L] </IfModule>
关键是把+FollowSymLinks合并到初始的Options配置中,避免后续规则覆盖。
4. 备选方案:用PHP代理绕过符号链接
如果以上方法都无效,直接用PHP脚本代理文件访问:
- 在
domain.com的根目录创建storage-proxy.php:
<?php $requestedFile = $_GET['f'] ?? ''; // 过滤非法路径,防止目录遍历 if (strpos($requestedFile, '..') !== false || empty($requestedFile)) { http_response_code(403); exit; } $fullPath = '/home/account/laravel-project/storage/app/public/' . $requestedFile; if (!file_exists($fullPath)) { http_response_code(404); exit; } // 输出文件 $mime = mime_content_type($fullPath); header("Content-Type: $mime"); readfile($fullPath); exit;
- 修改控制器中保存路径的代码:
$filePath = url('storage-proxy.php?f=uploads/img/' . $myFile->getClientOriginalName());
这种方式绕开符号链接限制,直接读取文件返回给浏览器。
5. 检查SELinux状态(若主机启用)
部分主机开启了SELinux,会阻止Apache访问用户目录下的符号链接。执行以下命令解决:
# 临时允许Apache访问用户目录 setsebool -P httpd_enable_homedirs on # 给目标目录添加正确的SELinux上下文 chcon -R -t httpd_sys_content_t /home/account/laravel-project/storage/app/public
内容的提问来源于stack exchange,提问作者mochiron.
相关产品推荐
相关产品推荐

