请问使用 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 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 17
AloneUtopia

proxy_pass 地址加 ‘/’ 试试----->proxy_pass http://cp01.erp.xxx.com:8000/

4年前 评论
arunfung

laravel项目可以使用子域名解决这个问题子域名

4年前 评论

这个明显是你代码问题,前端资源引用的 URI 可能是 // 开头。另外至少需要贴出来相关代码和配置,这样别人才好帮你改进,而不是看完你的描述,试图写一套完整的、可用的配置丢给你直接用。

4年前 评论

@Wi1dcard 我只是想咨询一下看看有没有人遇到类似问题,这个问题确实不好描述,因为有些部分涉及到隐私信息。我和朋友讨论的结果是无解,找网上其他的答案,也是没有找到解决方法。 :sweat_smile:

4年前 评论

@arunfung 我知道可以用子域名,但是目前要求使用二级目录

4年前 评论

@AloneUtopia 已经加了,并没有用 :sob:

4年前 评论

@Wi1dcard 我的问题类似这个,问答:nginx 如何整合多套系统? 可能描述的不太清楚哈,抱歉

4年前 评论

在不修改代码的前提下,如果想要在 Nginx 层面解决问题。有两个思路:

  1. 使用 redirecttry_files 指令,当客户访问 /vendor/... 时,重写至 /cms/vendor/...
  2. 使用 ngx_http_sub_module 模块提供的 sub_filter 指令,将 HTTP 响应中所有的 /vendor/... 替换为 /cms/vendor/...

第一种方式浏览器加载页面后,还是去访问 /vendor/... 内的资源,但 Nginx 重写至 /cms/vendor/... 并从重写后的 URI 拿到真实资源。

第二种方式浏览器加载页面时,Nginx 已经对页面(响应)内的 /vendor/... 做了替换。也就是说,浏览器看到的资源链接就是 /cms/vendor/...

相比较之下,虽然效果无异,对于客户端(浏览器)整个过程都是等效的。第二种略微更加消耗资源一点,但更加优雅。如果是我的话,我选择第二种。

4年前 评论

@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:

4年前 评论

@LiCxi 这是个常见到不能再常见的场景了,一般不会是设计缺陷,了解下 Laravel 的 TrustedProxy

另外我不明白为什么在同一个域名下行不通?可以用 location 块配合 rewrite 区分即可。

最后,用绝对路径是下下策,如果是我的话,绝对不会用这么粗暴的方式来解决。

4年前 评论
前端猫哥

@licxisky 今天也遇到了这个问题,这个应该不属于框架没想到,框架在生成 url 的时候并不知道你当前的地址是反向代理过来的,所以取根路径的时候不会把虚拟目录加上,因此想到的解决办法是在生成 url 的时候判断一下当前地址,如果是你的反向代理服务器,就把根路径手动添加虚拟目录

4年前 评论

@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...

4年前 评论
mouyong

@licxisky 这样?

file

file

4年前 评论
licxisky (楼主) 4年前
godruoyi

你可以试试配置多个二级目录呀,Nginx 配置二级目录支持

4年前 评论

@godruoyi 尝试过了,还是不行 :sweat_smile:,遇到问题后,能找到的所有方法都尝试过,然仍然不行。这个问题不是nginx的,是 laravel-admin url 解析的问题,nginx 层面无法解决 :smile:

4年前 评论
前端猫哥

@licxisky 没用过 laravel-admin ,虽然感觉是方便了,但就是怕有坑,没敢用。

貌似可以使用 app('url')->forceRootUrl($rootUrl) 来强行设置 url() 函数生成地址时的根地址,试过了吗,只要 laravel-admin 生成 url 也是用的 url() 这些函数,就可以解决

另外,用虚拟目录来做多个网站还是不方便,如果能用子域名就用子域名吧,那个是没任何问题的。

4年前 评论

@SadCreeper 很早就尝试过了,确实能解决 public 下的静态资源的问题,但是,页内动态生成的地址又会出问题。。。 :sob: :sob: :sob:

4年前 评论

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