在IIS 10子目录运行Laravel 11遇404/空白页问题求助
IIS 10下Laravel 11子目录路由404问题解决
问题背景
同一台IIS 10服务器上运行两个Laravel应用:Laravel 10运行正常,部署在new-app子目录的Laravel 11应用,访问根路径(http://www.maydomain.com/new-app)正常,但访问子路由(如http://www.maydomain.com/new-app/test)时出现404错误或空白页。
现有配置详情
1. 子目录new-app中的web.config
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <!-- Remove trailing slash --> <rule name="Remove trailing slash" stopProcessing="true"> <match url="^(.*)/$" ignoreCase="false" /> <action type="Redirect" redirectType="Permanent" url="/{R:1}" /> </rule> <!-- Rewrite requests to subdirectory "new-app" --> <rule name="Rewrite to index.php" stopProcessing="true"> <match url="^new-app/(.*)$" /> <conditions> <!-- If the request is not a directory or a file --> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> </conditions> <action type="Rewrite" url="/new-app/index.php/{R:1}" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
2. Laravel 11的.env配置
APP_URL=http://www.maydomain.com/new-app APP_DEBUG=true
3. Laravel路由(routes/web.php)
Route::get('/', function () { return view('welcome'); }); Route::get('/test', function () { return view('welcome'); }); Route::get('/test/{id}', function () { return view('welcome'); });
问题细节
- 访问
http://www.maydomain.com/new-app/test时出现404或空白页; - Laravel的
storage/logs无日志生成,IIS中无详细错误信息; - 直接访问
http://www.maydomain.com/new-app/index.php正常,说明Laravel应用本身可运行。
已执行的排查步骤
- 验证web.config语法并更新重写规则;
- 检查文件权限,确认public目录存在index.php;
- 设置.env中的APP_URL;
- 清除Laravel缓存(
php artisan config:clear等); - 启用IIS详细错误报告;
- 创建简单路由测试Laravel请求处理能力。
问题解答
1. 子目录运行Laravel是否需要额外的IIS配置?
需要,核心问题出在web.config的重写规则和IIS应用配置上:
- web.config位置与规则调整:如果web.config放在Laravel的
public目录(即IIS子应用的物理路径),则规则中的match url不应包含new-app——因为IIS会将当前子目录作为URL的根路径。正确的重写规则应改为:
同时,移除 trailing slash规则中的绝对路径,改为相对路径:<rule name="Rewrite to index.php" stopProcessing="true"> <match url="^(.*)$" /> <conditions> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> </conditions> <action type="Rewrite" url="index.php/{R:1}" /> </rule><rule name="Remove trailing slash" stopProcessing="true"> <match url="^(.*)/$" ignoreCase="false" /> <action type="Redirect" redirectType="Permanent" url="{R:1}" /> </rule> - IIS应用程序池配置:确保子应用的程序池设置为
.NET CLR版本: 无托管代码,因为Laravel是PHP应用,不需要.NET托管环境。 - URL重写模块:确认IIS已安装URL重写模块(可通过IIS管理器的“模块”查看,未安装需从微软官网下载安装)。
2. Laravel路由在子目录下是否存在问题?
Laravel路由本身无需修改,只要请求能正确传递到index.php,路由就能正常解析。当前问题的根源是重写规则未将子路由请求转发给Laravel的入口文件,而非Laravel路由逻辑问题。
另外需确认:
- IIS子应用的物理路径是否指向Laravel的
public目录(而非整个Laravel项目根目录)——这是部署Laravel的标准做法,避免暴露敏感文件。 .env中的APP_URL已正确设置为子目录路径,确保Laravel生成的链接、资源路径正确。
3. 遗漏的排查步骤或配置?
还有以下关键步骤需检查:
- 测试直接路由到index.php:访问
http://www.maydomain.com/new-app/index.php/test,如果能正常返回页面,说明Laravel路由逻辑正常,问题完全在IIS重写规则。 - 检查PHP错误日志:查看php.ini中
error_log配置的日志文件,可能Laravel日志未生成是因为PHP层面的错误未被捕获(如权限问题导致无法写入storage目录)。 - 确认应用程序池权限:确保应用程序池的身份(如
IIS AppPool\你的应用池名称)对Laravel的storage、bootstrap/cache目录有读写权限。 - 清除路由缓存:执行
php artisan route:clear,避免路由缓存导致的异常。 - 检查IIS子应用设置:在IIS管理器中,确认
new-app是作为应用程序(而非虚拟目录)创建的,虚拟目录可能导致重写规则失效。
内容的提问来源于stack exchange,提问作者kybdev
相关产品推荐
相关产品推荐

