背景:
前后分离应用:
除非页面显示跳转,大部分前端点击功能的数据获取和交互都是从服务器上的前端应用发出到 服务器上的后端应用 而不是浏览器发出 也就是7层的代理例如nginx/ingress只是到前端应用
前后一体:
大部分页面里的功能都要向 服务器应用发送请求,元素绑定的PATH是什么,请求就会变成什么,而且是从浏览器发给nginx.
需求:
nginx作为入口,只开放一个端口,按照path前缀代理到不同应用,其中 以 /fla/ 开头的请求都代理到一个前后端不分离的flask应用,页面渲染和处理还是要从应用那边处理:
server {
listen 8080;
server_name 172.188.73.105;
#根据url前缀来代理,同时去掉匹配前缀再发给应用 不用rewrite的方式
location /fla-no-rewirte/ {
# 匹配 /fla 的话 访问 /fla/login 实际传到app的是 //login a后的全部代理过去;
#/fla/ 会当作匹配关键字,只传/fla/login中的login, app收到/login
proxy_pass http://127.0.0.1:5000/ ;
}
# rewirte 方式 break 重写后不再进行下一个location匹配;当前url不跳转
# last 会在rewrite后作为下一跳 继续匹配location
location /fla/ {
#rewrite /flask(.*)$ $1 break;
proxy_pass http://127.0.0.1:5000;
}
# 处理静态文件请求 非通用
location ~ /static/ {
proxy_pass http://127.0.0.1:5000 ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /test/ {
proxy_pass http://127.0.0.1:5001/ ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /swagui/ {
proxy_pass http://127.0.0.1:999/ ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
问题:
当前 浏览器url里 /fla/ 这个匹配头,是我手动添加到path的,nginx收到请求能正常代理到应用的login页面
但是登陆后 点击某个功能 页面一旦跳转,因为静态文件里写的路径又不带匹配头 例如/test,/home/article,这些Url再次被发到nginx,由于nginx中并没有注册任何于此相关的location,所以收到后就不知道代理给谁了,然后就返回404报错,flask应用也没收到请求。
思来想去解决办法有2种:
办法一 修改应用和页面 改动量大:
flask应用中通过配置想字符串的形式设置一个prefix='/fla'类似的变量,然后添加到全部的试图函数rule,也就是app.route(rule: str)
然后给所有的前端页面元素绑定的跳转url通过render_template时添加上这一个前缀变量prefix,然后修改所有静态文件 添加 {{ prefix }}的引用。
这样就比较灵活的可以选择是否添加url 匹配头,统一修改匹配头。
此时nginx代理的时候就不需要去掉path中的匹配头了,匹配成功后直接发送给应用即可。
办法二 只修改前端页面中绑定的url 保留匹配头
为前端页面上绑定的url都添加上匹配头 /fla/ 后, 然后 nginx 匹配后 去掉匹配头 然后传递给应用 地址栏也不用修改
办法三 页面和应用都改 去掉匹配头
为前端页面上绑定的url都添加上匹配头 /fla/ 后, 然后 nginx 匹配后 不rewrite去掉匹配头 然后传递给应用,
flask应用那边在路由匹配前,手动进行匹配头的去除,这就类似于vue中去掉匹配头的方法一样。
#要在路由匹配发生在 ctx.push(),而before_request在preprocess这一步,在ctx_push之后了
# ctx.push中执行match,实际匹配结果 存放在 ctx.request.url_rule, ctx.view_args 最后dispatch_request()用直接引用 执行对应的视图函数
# 修改URL的位置: Map对象的 bind_to_environ()或者bind() 函数
# 尝试在此处生成MapAdaptor对象前修改请求match前的url, app.url_map.bind_to_environ
path_info = _get_wsgi_string("PATH_INFO")
if path_info.startswith("/fla"):
path_info = path_info.replace("/fla",'')
print(f'path_info modified at #line 351 map.py')
2776

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



