多子域名路由加上强制路由,无法使用

wybwsk

问题描述

前后端分离的TP项目,想转webman,基础的路由实现不了,不知道是不是用法错了。

"workerman/webman-framework": "^1.4.3",
PHP:8.0
OS: Ubuntu 20....

子域名配合nginx加上默认路由OK,https://www.workerman.net/q/7922
但是想强制自定义的类路由就没办法实现。因为我们原来的项目是使用强制路由,就是没定义路由的方法,写了也不让访问。
目录结构
app
|--api
|----controller
|------v1
|--------IndexController.php

绑定关系
/config/plugin/webman/domain/app.php

'bind'   => [
    'api.test.com'      => 'api', // 绑定到blog应用
],

使用默认路由
/config/route.php

use Webman\Route;
Route::fallback(function () {
    return response(json_encode(['code' => 404, 'msg' => 'Api Fail']), 404, ['Content-Type' => 'application/json']);
});

访问http://api.test.com/v1/Index/index.正常.

使用自定义路由 + 默认路由

use Webman\Route;

Route::group('/v1', function () {
    Route::get('/Index/index', [app\api\controller\v1\IndexController::class, 'index']);
});

Route::fallback(function () {
    return response(json_encode(['code' => 404, 'msg' => 'Api Fail']), 404, ['Content-Type' => 'application/json']);
});

访问http://api.test.com/v1/Index/index.正常,不冲突,或者是没有到这里.

使用自定义路由 + 关闭默认路由

use Webman\Route;

Route::group('/v1', function () {
    Route::get('/Index/index', [app\api\controller\v1\IndexController::class, 'index']);
});

Route::fallback(function () {
    return response(json_encode(['code' => 404, 'msg' => 'Api Fail']), 404, ['Content-Type' => 'application/json']);
});
Route::disableDefaultRoute();

访问http://api.test.com/v1/Index/index.异常,404.

使用自定义路由 + 关闭默认路由(去掉分组,用基础的类路由)

use Webman\Route;
Route::get('/v1/Index/index', [app\api\controller\v1\IndexController::class, 'index']);

Route::fallback(function () {
    return response(json_encode(['code' => 404, 'msg' => 'Api Fail']), 404, ['Content-Type' => 'application/json']);
});
Route::disableDefaultRoute();

访问http://api.test.com/v1/Index/index.异常,404.

另外,多应用的能否使用项目路由?因为应用多了的话,全写在route.php里面,文件太多了,要改的时候难找。

为此你搜索到了哪些方案及不适用的原因

搜索了多应用+多域名的解决方案,路由失效的解决方案。
这里写搜到的方案及不适用原因
单独的都有,合在一起的没找到对应的解决方案。

1067 2 1
2个回答

yongdao35

不发下nginx配置?

  • wybwsk 2022-12-31

    nginx配置和那文件一模一样的。。https://www.workerman.net/q/7922

    根据域名重写url

    if ($host = 'api.test.com') {
    rewrite ^/(.*)$ /api/$1 last;
    }

  • yongdao35 2022-12-31

    这个nginx配置的含义是自动给url的path加一个前缀api。比如你访问http://api.test.com/v1/Index/index,nginx会自动将地址变为http://api.test.com/api/v1/Index/index并转发给webman。但是你webman关闭了自动路由,也没有给/api/v1/Index/index设置路由,所以404了。我觉得你把

    if ($host = 'api.test.com') {
       rewrite ^/(.*)$ /api/$1 last;
    }

    这个配置删除了就好了

  • yongdao35 2022-12-31

    nginx配置删除后记得重启nginx

  • wybwsk 2023-01-01

    对的,可以了。api.test.com/abc api.test.com/test 能够用到域名绑定了
    在路由外面多加一层route::group('/api')就可以了。
    但是新问题出来了。

    Route::group('/api', function () {
        Route::group('/v1', function () {
            Route::get('/test', [app\api\controller\v1\IndexController::class, 'index']);
        });
    });
    //以上代码正常。
    
    Route::group('/api', function () {
        Route::group('/v1', function () {
            Route::get('/index/index', [app\api\controller\v1\IndexController::class, 'index']);
        });
    });
    //这个和默认路由是有冲突的,所以这个就直接报404了。

    这块不知道老大的路由思路是什么,开始还以为,Route::disableDefaultRoute()应该是个总开关。。true,就将所有的默认解析全关了,全用用户自己的,一个都没有定义就全部404。。
    false,就混和,默认的先定义,用户自定义的后定义,那么就是后定义的覆盖以前定义的进行处理,最终key是唯一的。
    后面发现这个Route::disableDefaultRoute()是需要放在路由配置最后面,可能是默认和自定义的在两个地方?还需要多看看源码。

    感谢大佬,问题解决了。。

  • keytehu 2023-01-01

    我看过源码,默认路由不会和你的路由有冲突,如果404,说明你地址访问错了,或者对应的路由确实没有设置。
    根据你的上下文来看,估计是访问的地址的错了,你给/api/v1/index/index(注意都是小写) 设置了路由,但是可能你去访问/api/v1/Index/index了(Index大写)

  • wybwsk 2023-01-03

    用tp习惯了,访问的时候有注意这个大小写。api/v1/index/index和api/v1/Index/index,这都是自己去定义的访问路径。。然后两种都试过,都是404.
    反正就是用上了域名插件,然后使用多应用,再自定义类路由的时候,关闭默认路由,自定义的路由就不能和以前默认的一样,如果一样,就404...
    这个试的步骤是这样的。每一步都先清空路由配置。
    1,注释所有自定义路由,打开默认路由。访问/api/v1/index/index OK
    2,自定义/api/v1/aaaa,打开默认路由。访问/api/v1/index/index OK ,访问/api/v1/aaaa OK
    3、自定义/api/v1/aaaa,关闭默认路由。访问/api/v1/index/index 404,访问/api/v1/aaaa OK
    3、自定义/api/v1/index/index,关闭默认路由。访问/api/v1/index/index 404

wybwsk

解决了。。不要安装webman/domain多域名插件,就使用项目默认的路由。
然后参照https://www.workerman.net/q/7922来配置。

nginx
在nginx配置中,不要按文档里面的去添加代理。比如我的webman默认端口10086.
按文档的话要在nginx中添加

upstream webman {
    server 127.0.0.1:10086;
    keepalive 10240;
}

这一段不要加。
就在

server
{
    listen 80;
    server_name adminapi.test.com api.test.com;
    index index.php index.html index.htm default.php default.htm default.html;
    root /www/wwwroot/api.test.com/public;

    include /www/wwwroot/api.test.com/nginx/*.conf;  //加上这一条,代理和rewrite配置都写在项目文件里。

然后在项目的根目录下添加nginx目录,建两个文件,一个文件也行。。一个代理配置,一个rewrite配置。
/api.test.com
|--nginx
|----proxy.conf
|----rewrite.conf
proxy.conf

location ^~ /
{
        if (!-e $request_filename){
           proxy_pass http://127.0.0.1:10086;
        }
         #设置域名 不加这个webman获取不到用户IP
        proxy_set_header Host $host;
        #设置用户IP 不加这个webman获取不到用户IP
        proxy_set_header X-Real-IP $remote_addr;
        #这个我也不知道干啥的反正加上就对了
        proxy_set_header REMOTE-HOST $remote_addr;
        #不需要关闭nginx缓存删掉下面这行
        proxy_cache off;
}

rewrite.conf
if (-f $request_filename){
break;
}

根据域名重写url

if ($host = 'adminapi.test.com') {
rewrite ^/(.*)$ /adminapi/$1 last;
}

根据域名重写url

if ($host = 'api.test.com') {
rewrite ^/(.*)$ /api/$1 last;
}

然后这时,/config/route.php里面的路由就跟TP的一样了,强制路由,子域名绑定。

use Webman\Route;

Route::group('/adminapi', function () {
    Route::get('/test', [app\adminapi\controller\v1\IndexController::class, 'index']);
    Route::get('/v1/Index/index', [app\adminapi\controller\v1\IndexController::class, 'index']);
});

Route::group('/api', function () {
    Route::get('/test', [app\api\controller\v1\IndexController::class, 'index']);
//    Route::get('/v1/Index/index', [app\api\controller\v1\IndexController::class, 'index']);
});
Route::disableDefaultRoute();
  • 暂无评论
年代过于久远,无法发表回答
🔝