请问使用 nginx 进行反向代理 Laravel 项目的时候如何 保障 Laravel 项目下静态资源的访问 ?
在不使用子域名的情况下,如何整合多个 Laravel 系统到同一个域名下,
// 项目:a, b
// 目标
http://domain.com/a
http://domain.com/b
目前通过 nginx 的反向代理可以实现路由的代理,但当涉及到 public 文件夹下的静态资源的时候,因为 laravel 本身的原因,静态资源的绝对路径会依赖于代理连接的 host, 也就是项目中的
assert("jquery.js");
被解析为:http://domain.com/jquery.js
实际上是:http://domain.com/a/jquery.js
已经有人遇到过此类问题 问答:nginx 如何整合多套系统? ,但没有解决,我和同事交流出来也是无解(指仅仅配置nginx,在不动现有PHP代码的情况下),
想请教一下是否有人遇到过此类问题?
------------------------- 2019-06-09 ----------------------------
目前问题定位是出在 laravel-admin 上
本作品采用《CC 协议》,转载必须注明作者和本文链接
proxy_pass 地址加 ‘/’ 试试----->proxy_pass http://cp01.erp.xxx.com:8000/
laravel项目可以使用子域名解决这个问题子域名
这个明显是你代码问题,前端资源引用的 URI 可能是
//
开头。另外至少需要贴出来相关代码和配置,这样别人才好帮你改进,而不是看完你的描述,试图写一套完整的、可用的配置丢给你直接用。@Wi1dcard 我只是想咨询一下看看有没有人遇到类似问题,这个问题确实不好描述,因为有些部分涉及到隐私信息。我和朋友讨论的结果是无解,找网上其他的答案,也是没有找到解决方法。 :sweat_smile:
@arunfung 我知道可以用子域名,但是目前要求使用二级目录
@AloneUtopia 已经加了,并没有用 :sob:
@Wi1dcard 我的问题类似这个,问答:nginx 如何整合多套系统? 可能描述的不太清楚哈,抱歉
在不修改代码的前提下,如果想要在 Nginx 层面解决问题。有两个思路:
redirect
或try_files
指令,当客户访问/vendor/...
时,重写至/cms/vendor/...
。ngx_http_sub_module
模块提供的sub_filter
指令,将 HTTP 响应中所有的/vendor/...
替换为/cms/vendor/...
。第一种方式浏览器加载页面后,还是去访问
/vendor/...
内的资源,但 Nginx 重写至/cms/vendor/...
并从重写后的 URI 拿到真实资源。第二种方式浏览器加载页面时,Nginx 已经对页面(响应)内的
/vendor/...
做了替换。也就是说,浏览器看到的资源链接就是/cms/vendor/...
。相比较之下,虽然效果无异,对于客户端(浏览器)整个过程都是等效的。第二种略微更加消耗资源一点,但更加优雅。如果是我的话,我选择第二种。
@Wi1dcard 这种方案在单项目中可以使用,但如果是多项目的话,
例如:
http://domain.com/cms/vendor/...
http://domain.com/erp/vendor/...
两个及以上的项目在一个域名下就行不通了,因为使用的是同一套后台解决方案,laravel-admin,所以就静态资源有一部分是一致的,还有一些不一致(可能重名)
现在在考虑是否是 Laravel 本身设计的机制问题。当然,这个问题可以完全在编码中解决,比如 资源地址使用 绝对路径 等等,但因为后台使用的是 laravel-admin,所以不想改动 laravel-admin 的源码。感觉这是一个 框架 的问题,框架对于代理后的地址,assert() 解析上存在一些问题。
浏览器输入
http://domain.com/cms/admin
nginx 代理到
http://cp01.erp.xxx.com:8000/admin
Laravel 项目解析路由为
/admin
Laravel 项目中的方法
assert('vendor/jquery.js')
为http://domain.com/vendor/jquery.js
实际上应该为
http://domain.com/cms/vendor/jquery.js
问题最终定位在这边,我认为应该是框架没有考虑到这种情况,但。。。不够自信,想拿出来给大家讨论一下 :sweat_smile:
@LiCxi 这是个常见到不能再常见的场景了,一般不会是设计缺陷,了解下 Laravel 的
TrustedProxy
。另外我不明白为什么在同一个域名下行不通?可以用
location
块配合rewrite
区分即可。最后,用绝对路径是下下策,如果是我的话,绝对不会用这么粗暴的方式来解决。
@licxisky 今天也遇到了这个问题,这个应该不属于框架没想到,框架在生成 url 的时候并不知道你当前的地址是反向代理过来的,所以取根路径的时候不会把虚拟目录加上,因此想到的解决办法是在生成 url 的时候判断一下当前地址,如果是你的反向代理服务器,就把根路径手动添加虚拟目录
@SadCreeper 不知道你是否使用的是 laravel-admin,经过研究后,我发现应该是 laravel-admin 的问题,laravel 可以通过设置 .env 中的 APP_URL 来通知框架为反向代理的地址,但 laravel-admin 并没有考虑到这一点(其实是考虑到了,laravel-admin issue里16年就有人提过这个BUG,但后来被作者关闭了。。。 :joy:)但现在关于这个问题还没理太清楚,关于如何修复这个BUG提PR也没什么头绪(还是自己太菜了 :sweat_smile:)
https://github.com/z-song/laravel-admin/is...
@licxisky 这样?
你可以试试配置多个二级目录呀,Nginx 配置二级目录支持
@godruoyi 尝试过了,还是不行 :sweat_smile:,遇到问题后,能找到的所有方法都尝试过,然仍然不行。这个问题不是nginx的,是 laravel-admin url 解析的问题,nginx 层面无法解决 :smile:
@licxisky 没用过 laravel-admin ,虽然感觉是方便了,但就是怕有坑,没敢用。
貌似可以使用
app('url')->forceRootUrl($rootUrl)
来强行设置 url() 函数生成地址时的根地址,试过了吗,只要 laravel-admin 生成 url 也是用的 url() 这些函数,就可以解决另外,用虚拟目录来做多个网站还是不方便,如果能用子域名就用子域名吧,那个是没任何问题的。
@SadCreeper 很早就尝试过了,确实能解决 public 下的静态资源的问题,但是,页内动态生成的地址又会出问题。。。 :sob: :sob: :sob: