nginx 重写后,laravel 路由显示404

1. 运行环境

laravel/framework: “^8.75”
PHP 版本:8.0
nginx 版本:1.15.11

2. 问题描述

nginx 配置如下

server {
        listen        93;
        server_name  localhost;
        root   "F:/project/work/gameWeb/public/";
        location /m/ {
            rewrite ^/m/(.*)$ /index.php$1 break;
        }
        location / {
            index index.php index.html error/index.html;
            try_files $uri $uri/ /index.php$is_args$args;
        }
        location ~ \.php(.*)$ {
            fastcgi_pass   127.0.0.1:9002;
            fastcgi_index  index.php;
            fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO  $fastcgi_path_info;
            fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
            include        fastcgi_params;
        }
}

laravel 路由配置文件如下

Route::get('/register', 'Auth\RegisterController@showRegistrationForm');

我访问路径:localhost:93/register 正常
访问路径:localhost:93/m/register 会出现路由匹配不上,404的问题

3. 个人理解

我的个人理解是,nginx的rewrite重写,并不会改变$_SERVER[‘REQUEST_URI’] 的值,也就是说,rewrite虽然将 /m/register 重写成了 /register,但是程序是拿 $_SERVER[‘REQUEST_URI’] 的值进行路由对比,但是重写并未改变 $_SERVER[‘REQUEST_URI’] ,所以拿 /m/register 对比路由会匹配失败,从而导致404的产生

我没去阅读源码,不知道我的理解对不对?

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案
rewrite regex replacement [flag];

参考下flag的说明文档:

last:本条重写规则匹配完成后,终止匹配后续重写规则,并重新发起请求继续匹配新的location URI规则;浏览器地址栏URL地址不变
break:本条重写规则匹配完成后,终止匹配后续重写规则; 浏览器地址栏URL地址不变
redirect:返回302临时重定向,浏览器地址会显示重写后的URL地址
permanent:返回301永久重定向,浏览器地址会显示重写后的URL地址

last和break,并不会改变URL地址,因此REQUEST_URI并不会改变,如果要改变需要使用redirect和permanent。

3个月前 评论
fendouweiqian (楼主) 3个月前
lovewei (作者) 3个月前
讨论数量: 4
rewrite regex replacement [flag];

参考下flag的说明文档:

last:本条重写规则匹配完成后,终止匹配后续重写规则,并重新发起请求继续匹配新的location URI规则;浏览器地址栏URL地址不变
break:本条重写规则匹配完成后,终止匹配后续重写规则; 浏览器地址栏URL地址不变
redirect:返回302临时重定向,浏览器地址会显示重写后的URL地址
permanent:返回301永久重定向,浏览器地址会显示重写后的URL地址

last和break,并不会改变URL地址,因此REQUEST_URI并不会改变,如果要改变需要使用redirect和permanent。

3个月前 评论
fendouweiqian (楼主) 3个月前
lovewei (作者) 3个月前

我最终的解决方案是RouteServiceProvider.php文件下的boot方法中,创建一个有前缀的路由 有m前缀和没有m前缀都使用同一个路由规则

public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));

           // 没有m前缀的路由
            Route::namespace('App\User\Controller')
                ->group(base_path('routes/user.php'));

          // 有m前缀的路由
            Route::prefix('m')
                ->namespace('App\User\Controller')
                ->group(base_path('routes/user.php'));
        });
    }
3个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!