Laravel 和 Dcat Admin 在使用 Nginx 进行 Uri 二级目录的反向代理时遇到的问题以及解决方法

8 篇文章 0 订阅
5 篇文章 1 订阅

问题

一般的 Laravel 应用进行 Nginx 的 Uri 二级目录反向代理的时候,Nginx 的配置文件可按如下配置

location /prefix/ {
    set $suffix "";

    if ($uri = /index.php) {
        set $suffix /;
    }

    proxy_http_version 1.1;
    proxy_set_header Host $http_host;
    proxy_set_header Scheme $scheme;
    proxy_set_header SERVER_PORT $server_port;
    proxy_set_header REMOTE_ADDR $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    proxy_pass http://127.0.0.1:8000/;
}

由于我们在 proxy_pass 中的 Url 末尾添加了 /,所以 Laravel 在收到请求时,请求的路径不包含反向代理的前缀 /prefix,即若用户所见的地址为:

http://xxxx.xxxx/prefix/index

Laravel 收到的请求地址将会是:

http://xxxx.xxxx/index

这样就可以让反向代理层对 Laravel 应用透明,但是会出现这样的问题,就是 url() 等函数生成的路径将会是不含反向代理前缀的路径,造成 asset() 等函数均生成错误的地址,为了解决这样的问题,我们可以在 AppServiceProvider 类中的 boot 方法添加以下内容:

app('url')->forceRootUrl(config(app.url));

这样的话,url() 将会基于 .env 文件中提供的 APP_URL 值设置所生成的 url 的根路径。我们只需在 .env 中配置 APP_URL 即可

APP_URL=http://xxxx.xxxx/prefix/

经过这样的配置,对于一般的 Laravel 应用已经可以实现二级目录的反向代理,但实际上很多项目中生成 url 的地方并非都使用 url() 函数生成,比如今天要说的 Dcat Admin,它的源代码中同时使用了 $request 的 url 和 url() 生成的 url 。如在生成菜单项时使用了 url() 函数而在获取当前资源路径时,当 $request 提供的 url 合法的话又是直接使用请求的地址。

这就导致我们在使用上面的的配置的时候,会出现这样的情况:

  • 点击菜单栏跳转到 /prefix/xxx 之后,地址栏会自动变成 /xxx ,刷新后变成了 404;
  • “创建”、“提交”按钮提供的是不带 prefix 的链接,导致 404

解决方法

在上述配置的基础上,在 admin.php中将后台的路径配置为 /prefix/admin ,然后再在 Nginx 的配置文件中添加:

location /prefix/admin/ {
    set $suffix "";

    if ($uri = /index.php) {
        set $suffix /;
    }

    proxy_http_version 1.1;
    proxy_set_header Host $http_host;
    proxy_set_header Scheme $scheme;
    proxy_set_header SERVER_PORT $server_port;
    proxy_set_header REMOTE_ADDR $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;


    proxy_pass http://127.0.0.1:8000;
}

注意这里面 proxy_pass 末尾没有添加 /,Laravel 接收到请求时将会保有 /prefix/admin

当我们这样配置时,Dcat Admin 会生成两种 url,一种是 /prefix/prefix/admin/(使用 url() 函数生成的),一种是 /prefix/admin/xxx (直接从请求的 url 中获取的)。

当访问 /prefix/prefix/admin/ 时,会被 Nginx 中的 location /prefix/ 捕获,Laravel 应用收到的 Uri 不带 /prefix ,即 /prefix/admin,按照我们在 admin.php 中的配置,此时请求成功被 Dcat Admin 捕获并处理。

当访问 /prefix/admin/xxx 时,会被 Nginx 中的 location /prefix/admin/ 中捕获,此时 Laravel 收到的请求会保有 /prefix/admin ,此时请求成功被 Dcat Admin 捕获并处理。

改进

暂时没有改进的思路,还望各位大佬指点。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值