问题
一般的 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 捕获并处理。
改进
暂时没有改进的思路,还望各位大佬指点。

本文详细介绍了如何配置Nginx以实现Laravel应用在二级目录下的反向代理,以及解决由此引发的URL生成错误和DcatAdmin路径问题。通过修改Nginx配置和Laravel的URL设置,确保了url()和asset()函数正确生成地址,并针对DcatAdmin的特殊情况进行调整,避免了404错误。

695

被折叠的 条评论
为什么被折叠?



